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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits