https://github.com/frank-515 updated 
https://github.com/llvm/llvm-project/pull/190209

>From e08975fe26db42665a19ad14270cfb575170757f Mon Sep 17 00:00:00 2001
From: frank515 <[email protected]>
Date: Fri, 3 Apr 2026 00:03:50 +0800
Subject: [PATCH] [clang-format] Fix extraneous space in block comments ending
 with **/

This patch fixes an issue where ReflowComments incorrectly inserts an extra 
space
inside comment lines when the block comment ends with **/.

Fixes #187764
---
 clang/lib/Format/BreakableToken.cpp           | 16 ++++++++++------
 clang/unittests/Format/FormatTestComments.cpp |  9 +++++++++
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Format/BreakableToken.cpp 
b/clang/lib/Format/BreakableToken.cpp
index b60daffc0eb1c..902d3f1d587ef 100644
--- a/clang/lib/Format/BreakableToken.cpp
+++ b/clang/lib/Format/BreakableToken.cpp
@@ -55,8 +55,7 @@ static StringRef getLineCommentIndentPrefix(StringRef Comment,
 static BreakableToken::Split
 getCommentSplit(StringRef Text, unsigned ContentStartColumn,
                 unsigned ColumnLimit, unsigned TabWidth,
-                encoding::Encoding Encoding, const FormatStyle &Style,
-                bool DecorationEndsWithStar = false) {
+                encoding::Encoding Encoding, const FormatStyle &Style) {
   LLVM_DEBUG(llvm::dbgs() << "Comment split: \"" << Text
                           << "\", Column limit: " << ColumnLimit
                           << ", Content start: " << ContentStartColumn << 
"\n");
@@ -145,9 +144,7 @@ getCommentSplit(StringRef Text, unsigned ContentStartColumn,
     if (SpaceOffset == 1 && Text[SpaceOffset - 1] == '*')
       return BreakableToken::Split(StringRef::npos, 0);
     StringRef BeforeCut = Text.substr(0, SpaceOffset).rtrim(Blanks);
-    StringRef AfterCut = Text.substr(SpaceOffset);
-    if (!DecorationEndsWithStar)
-      AfterCut = AfterCut.ltrim(Blanks);
+    StringRef AfterCut = Text.substr(SpaceOffset).ltrim(Blanks);
     return BreakableToken::Split(BeforeCut.size(),
                                  AfterCut.begin() - BeforeCut.end());
   }
@@ -601,7 +598,7 @@ BreakableToken::Split BreakableBlockComment::getSplit(
     return Split(StringRef::npos, 0);
   return getCommentSplit(Content[LineIndex].substr(TailOffset),
                          ContentStartColumn, ColumnLimit, Style.TabWidth,
-                         Encoding, Style, Decoration.ends_with("*"));
+                         Encoding, Style);
 }
 
 void BreakableBlockComment::adjustWhitespace(unsigned LineIndex,
@@ -703,6 +700,7 @@ void BreakableBlockComment::insertBreak(unsigned LineIndex, 
unsigned TailOffset,
                                         WhitespaceManager &Whitespaces) const {
   StringRef Text = Content[LineIndex].substr(TailOffset);
   StringRef Prefix = Decoration;
+  std::string PrefixStorage;
   // We need this to account for the case when we have a decoration "* " for 
all
   // the lines except for the last one, where the star in "*/" acts as a
   // decoration.
@@ -713,6 +711,12 @@ void BreakableBlockComment::insertBreak(unsigned 
LineIndex, unsigned TailOffset,
     Prefix = "";
     if (LocalIndentAtLineBreak >= 2)
       LocalIndentAtLineBreak -= 2;
+  } else if (!Prefix.empty() && Prefix.ends_with("*") && Split.second > 0) {
+    // getCommentSplit trims the whitespace at the split. Keep a visible space
+    // after star-only decorations by adding it to the inserted prefix.
+    PrefixStorage = Prefix.str();
+    PrefixStorage.push_back(' ');
+    Prefix = PrefixStorage;
   }
   // The split offset is from the beginning of the line. Convert it to an 
offset
   // from the beginning of the token text.
diff --git a/clang/unittests/Format/FormatTestComments.cpp 
b/clang/unittests/Format/FormatTestComments.cpp
index 684d3014fa7bb..3c821a4363ca3 100644
--- a/clang/unittests/Format/FormatTestComments.cpp
+++ b/clang/unittests/Format/FormatTestComments.cpp
@@ -1588,6 +1588,15 @@ TEST_F(FormatTestComments, ReflowsComments) {
                "   long */",
                Style20);
 
+  auto Style80 = getLLVMStyleWithColumns(80);
+  Style80.PenaltyExcessCharacter = 10;
+  StringRef ClosingStars = "/**\n"
+                           " * This test verifies the special code path. It "
+                           "currently exists for code coverage.\n"
+                           " **/\n"
+                           "void test() {}";
+  EXPECT_EQ(ClosingStars, format(ClosingStars, Style80));
+
   // Reflow two short lines; keep the postfix of the last one.
   verifyFormat("/* long long long\n"
                " * long long long */",

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to