[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