Skip to content

Conversation

@ZhongRuoyu
Copy link
Member

@ZhongRuoyu ZhongRuoyu commented Oct 20, 2025

Line comments in preprocessor directives were incorrectly marked as continuing the directive, causing clang-format to add backslashes after them on repeated runs. Backslashes appended after line comments in this way do not continue the PP directive because the following line would also become part of the comment.

Fix by unsetting InPPDirective in WhitespaceManager::replaceWhitespace for line comments in two places: when breaking lines and when formatting tokens on the same line. This stops the spurious backslash insertion for both standalone line comments after PP directives and trailing line comments after macro bodies.

Fixes #164282.

@llvmbot
Copy link
Member

llvmbot commented Oct 20, 2025

@llvm/pr-subscribers-clang-format

Author: Ruoyu Zhong (ZhongRuoyu)

Changes

Line comments in preprocessor directives were incorrectly marked as continuing the directive, causing clang-format to add backslashes after them on repeated runs. Line comments cannot span multiple lines with backslashes, so they should not be treated as PP directive continuations.

Fix by unsetting InPPDirective in WhitespaceManager::replaceWhitespace for line comments in two places: when breaking lines and when formatting tokens on the same line. This stops the spurious backslash insertion for both standalone line comments after preprocessor directives and trailing line comments after macro bodies.

Fixes #164282.


Full diff: https://github.com/llvm/llvm-project/pull/164300.diff

2 Files Affected:

  • (modified) clang/lib/Format/ContinuationIndenter.cpp (+6-3)
  • (modified) clang/unittests/Format/FormatTestComments.cpp (+19)
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index 26a95421775f3..1b0a2f001474d 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -798,9 +798,11 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
   }
 
   if (!DryRun) {
+    bool ContinuePPDirective =
+        State.Line->InMacroBody && Current.isNot(TT_LineComment);
     Whitespaces.replaceWhitespace(Current, /*Newlines=*/0, Spaces,
                                   State.Column + Spaces + PPColumnCorrection,
-                                  /*IsAligned=*/false, State.Line->InMacroBody);
+                                  /*IsAligned=*/false, ContinuePPDirective);
   }
 
   // If "BreakBeforeInheritanceComma" mode, don't break within the inheritance
@@ -1178,8 +1180,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
     }
     unsigned Newlines =
         std::max(1u, std::min(Current.NewlinesBefore, MaxEmptyLinesToKeep));
-    bool ContinuePPDirective =
-        State.Line->InPPDirective && State.Line->Type != LT_ImportStatement;
+    bool ContinuePPDirective = State.Line->InPPDirective &&
+                               State.Line->Type != LT_ImportStatement &&
+                               Current.isNot(TT_LineComment);
     Whitespaces.replaceWhitespace(Current, Newlines, State.Column, State.Column,
                                   CurrentState.IsAligned, ContinuePPDirective);
   }
diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp
index fc80bf4024fd9..f5c791a29ba02 100644
--- a/clang/unittests/Format/FormatTestComments.cpp
+++ b/clang/unittests/Format/FormatTestComments.cpp
@@ -839,6 +839,25 @@ TEST_F(FormatTestComments, MultiLineCommentsInDefines) {
                    getLLVMStyleWithColumns(17)));
 }
 
+TEST_F(FormatTestComments, LineCommentsInMacrosDoNotGetEscapedNewlines) {
+  FormatStyle Style = getLLVMStyleWithColumns(0);
+  Style.ReflowComments = FormatStyle::RCS_Never;
+  verifyFormat("#define FOO (1U) // comment\n"
+               "                 // comment",
+               Style);
+
+  Style.ColumnLimit = 32;
+  EXPECT_EQ("#define SOME_MACRO(x) x\n"
+            "#define FOO                    \\\n"
+            "  SOME_MACRO(1) +              \\\n"
+            "      SOME_MACRO(2) // comment\n"
+            "                    // comment",
+            format("#define SOME_MACRO(x) x\n"
+                   "#define FOO SOME_MACRO(1) + SOME_MACRO(2) // comment\n"
+                   "                                          // comment",
+                   Style));
+}
+
 TEST_F(FormatTestComments, ParsesCommentsAdjacentToPPDirectives) {
   EXPECT_EQ("namespace {}\n// Test\n#define A",
             format("namespace {}\n   // Test\n#define A"));

Copy link
Contributor

@HazardyKnusperkeks HazardyKnusperkeks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may also want to update the commit message, because line comments can be continued with \. https://godbolt.org/z/GP8YnoTqb

Line comments in preprocessor directives were incorrectly marked as
continuing the directive, causing clang-format to add backslashes
after them on repeated runs. Backslashes appended after line comments in
this way do not continue the PP directive because the following line
would also become part of the comment.

Fix by unsetting InPPDirective in WhitespaceManager::replaceWhitespace
for line comments in two places: when breaking lines and when formatting
tokens on the same line. This stops the spurious backslash insertion for
both standalone line comments after PP directives and trailing line
comments after macro bodies.

Fixes llvm#164282.

Co-authored-by: Björn Schäpers <bjoern@hazardy.de>
Signed-off-by: Ruoyu Zhong <zhongruoyu@outlook.com>
@ZhongRuoyu ZhongRuoyu force-pushed the clang-format-fix-backslash-in-macro-line-comments branch from 4f19c01 to f06121a Compare October 20, 2025 20:11
@ZhongRuoyu
Copy link
Member Author

You may also want to update the commit message, because line comments can be continued with \. https://godbolt.org/z/GP8YnoTqb

Thanks -- didn't think about that! I updated the PR description as well.

@HazardyKnusperkeks HazardyKnusperkeks merged commit 228a353 into llvm:main Oct 21, 2025
9 of 10 checks passed
Lukacma pushed a commit to Lukacma/llvm-project that referenced this pull request Oct 29, 2025
llvm#164300)

Line comments in preprocessor directives were incorrectly marked as
continuing the directive, causing clang-format to add backslashes after
them on repeated runs. Backslashes appended after line comments in this
way do not continue the PP directive because the following line would
also become part of the comment.

Fix by unsetting `InPPDirective` in
`WhitespaceManager::replaceWhitespace` for line comments in two places:
when breaking lines and when formatting tokens on the same line. This
stops the spurious backslash insertion for both standalone line comments
after PP directives and trailing line comments after macro bodies.

Fixes llvm#164282.

Signed-off-by: Ruoyu Zhong <zhongruoyu@outlook.com>
aokblast pushed a commit to aokblast/llvm-project that referenced this pull request Oct 30, 2025
llvm#164300)

Line comments in preprocessor directives were incorrectly marked as
continuing the directive, causing clang-format to add backslashes after
them on repeated runs. Backslashes appended after line comments in this
way do not continue the PP directive because the following line would
also become part of the comment.

Fix by unsetting `InPPDirective` in
`WhitespaceManager::replaceWhitespace` for line comments in two places:
when breaking lines and when formatting tokens on the same line. This
stops the spurious backslash insertion for both standalone line comments
after PP directives and trailing line comments after macro bodies.

Fixes llvm#164282.

Signed-off-by: Ruoyu Zhong <zhongruoyu@outlook.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[clang-format] Bug - clang-format keeps appending \ when ReflowComments: Never and ColumnLimit: 0

3 participants