[clang] [clang-format] Fix first-line width calculation for CRLF multiline tokens (PR #228752)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Oct 3 11:00:20 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-format
Author: w1m (w1m024)
<details>
<summary>Changes</summary>
The first-line width of a multiline token is calculated from the text before the first `LF`. For `CRLF` input, this includes the preceding `CR`, which is counted as an extra column and can change wrapping at the column limit.
Exclude the trailing `CR` when measuring the first-line width while preserving the token text. Add a regression test covering `LF` and `CRLF` multiline raw strings whose first line, including the preceding code, exactly fits the column limit.
Fixes #<!-- -->224571
Assisted-by: Codex
---
Full diff: https://github.com/llvm/llvm-project/pull/228752.diff
2 Files Affected:
- (modified) clang/lib/Format/FormatTokenLexer.cpp (+5-1)
- (modified) clang/unittests/Format/FormatTest.cpp (+17)
``````````diff
diff --git a/clang/lib/Format/FormatTokenLexer.cpp b/clang/lib/Format/FormatTokenLexer.cpp
index 2a8bef21ad4143..12a6fb8ea90540 100644
--- a/clang/lib/Format/FormatTokenLexer.cpp
+++ b/clang/lib/Format/FormatTokenLexer.cpp
@@ -1473,10 +1473,14 @@ FormatToken *FormatTokenLexer::getNextToken() {
Column += FormatTok->ColumnWidth;
} else {
FormatTok->IsMultiline = true;
+ // Exclude the '\r' of a CRLF line ending from the first line's width.
+ StringRef FirstLine = Text.substr(0, FirstNewlinePos);
+ if (FirstLine.ends_with("\r"))
+ FirstLine = FirstLine.drop_back();
// FIXME: ColumnWidth actually depends on the start column, we need to
// take this into account when the token is moved.
FormatTok->ColumnWidth = encoding::columnWidthWithTabs(
- Text.substr(0, FirstNewlinePos), Column, Style.TabWidth, Encoding);
+ FirstLine, Column, Style.TabWidth, Encoding);
// The last line of the token always starts in column 0.
// Thus, the length can be precomputed even in the presence of tabs.
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 0a5950c25c60ef..19e9f9695812e2 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -16681,6 +16681,23 @@ TEST_F(FormatTest, CountsCharactersInMultilineRawStringLiterals) {
" R\"(single line raw string)\" + bbbbbb);");
}
+TEST_F(FormatTest, MultilineRawStringWidthWithCRLF) {
+ auto Style = getWebKitStyle();
+ Style.ColumnLimit = 23;
+ Style.AllowAllArgumentsOnNextLine = false;
+ Style.PackArguments.BinPack = FormatStyle::BPAS_OnePerLine;
+
+ // The raw string's first line reaches ColumnLimit; CR must not add a column.
+ verifyFormat("x = a ? f(R\"(aaaaaaaaaa\n)\",\n"
+ " b)\n"
+ " : g();",
+ "x = a ? f(R\"(aaaaaaaaaa\n)\", b) : g();", Style);
+ verifyFormat("x = a ? f(R\"(aaaaaaaaaa\r\n)\",\r\n"
+ " b)\r\n"
+ " : g();",
+ "x = a ? f(R\"(aaaaaaaaaa\r\n)\", b) : g();", Style);
+}
+
TEST_F(FormatTest, SkipsUnknownStringLiterals) {
verifyFormat("string a = \"unterminated;");
verifyFormat("function(\"unterminated,\n"
``````````
</details>
https://github.com/llvm/llvm-project/pull/228752
More information about the cfe-commits
mailing list