[clang] cac6777 - [clang-format] Fix crashes when the macro expansion is empty (#119428)

via cfe-commits cfe-commits at lists.llvm.org
Sat Dec 21 22:21:31 PST 2024


Author: 天音あめ
Date: 2024-12-21T22:21:27-08:00
New Revision: cac6777ca14e162eb6e97e20da266802846ab953

URL: https://github.com/llvm/llvm-project/commit/cac6777ca14e162eb6e97e20da266802846ab953
DIFF: https://github.com/llvm/llvm-project/commit/cac6777ca14e162eb6e97e20da266802846ab953.diff

LOG: [clang-format] Fix crashes when the macro expansion is empty (#119428)

An empty expansion should be valid, like `echo 'A()' | clang-format
--style='{Macros: [A(x)=x]}'`.

Fixes #119258.

Added: 
    

Modified: 
    clang/lib/Format/MacroExpander.cpp
    clang/unittests/Format/MacroCallReconstructorTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Format/MacroExpander.cpp b/clang/lib/Format/MacroExpander.cpp
index fd2a16894d643d..ba2992889e6743 100644
--- a/clang/lib/Format/MacroExpander.cpp
+++ b/clang/lib/Format/MacroExpander.cpp
@@ -233,6 +233,10 @@ MacroExpander::expand(FormatToken *ID,
   if (Result.size() > 1) {
     ++Result[0]->MacroCtx->StartOfExpansion;
     ++Result[Result.size() - 2]->MacroCtx->EndOfExpansion;
+  } else {
+    // If the macro expansion is empty, mark the start and end.
+    Result[0]->MacroCtx->StartOfExpansion = 1;
+    Result[0]->MacroCtx->EndOfExpansion = 1;
   }
   return Result;
 }

diff  --git a/clang/unittests/Format/MacroCallReconstructorTest.cpp b/clang/unittests/Format/MacroCallReconstructorTest.cpp
index b4ee8d0e37efa8..b58241fd8c4e80 100644
--- a/clang/unittests/Format/MacroCallReconstructorTest.cpp
+++ b/clang/unittests/Format/MacroCallReconstructorTest.cpp
@@ -65,7 +65,9 @@ class Expansion {
     }
     Unexpanded[ID] = std::move(UnexpandedLine);
 
-    auto Expanded = uneof(Macros.expand(ID, Args));
+    auto Expanded = Macros.expand(ID, Args);
+    if (Expanded.size() > 1)
+      Expanded = uneof(Expanded);
     Tokens.append(Expanded.begin(), Expanded.end());
 
     TokenList UnexpandedTokens;
@@ -217,6 +219,31 @@ TEST_F(MacroCallReconstructorTest, Identifier) {
   EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(line(U.consume("X"))));
 }
 
+TEST_F(MacroCallReconstructorTest, EmptyDefinition) {
+  auto Macros = createExpander({"X"});
+  Expansion Exp(Lex, *Macros);
+  TokenList Call = Exp.expand("X");
+
+  MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
+  Unexp.addLine(line(Exp.getTokens()));
+  EXPECT_TRUE(Unexp.finished());
+  Matcher U(Call, Lex);
+  EXPECT_THAT(std::move(Unexp).takeResult(), matchesLine(line(U.consume("X"))));
+}
+
+TEST_F(MacroCallReconstructorTest, EmptyExpansion) {
+  auto Macros = createExpander({"A(x)=x"});
+  Expansion Exp(Lex, *Macros);
+  TokenList Call = Exp.expand("A", {""});
+
+  MacroCallReconstructor Unexp(0, Exp.getUnexpanded());
+  Unexp.addLine(line(Exp.getTokens()));
+  EXPECT_TRUE(Unexp.finished());
+  Matcher U(Call, Lex);
+  EXPECT_THAT(std::move(Unexp).takeResult(),
+              matchesLine(line(U.consume("A()"))));
+}
+
 TEST_F(MacroCallReconstructorTest, NestedLineWithinCall) {
   auto Macros = createExpander({"C(a)=class X { a; };"});
   Expansion Exp(Lex, *Macros);


        


More information about the cfe-commits mailing list