diff --git a/clang/lib/Tooling/Syntax/Tokens.cpp b/clang/lib/Tooling/Syntax/Tokens.cpp --- a/clang/lib/Tooling/Syntax/Tokens.cpp +++ b/clang/lib/Tooling/Syntax/Tokens.cpp @@ -614,10 +614,7 @@ unsigned MappingBegin = SpelledIndex; ++SpelledIndex; - bool HitMapping = - tryConsumeSpelledUntil(File, EndOffset + 1, SpelledIndex).hasValue(); - (void)HitMapping; - assert(!HitMapping && "recursive macro expansion?"); + (void)tryConsumeSpelledUntil(File, EndOffset + 1, SpelledIndex).hasValue(); TokenBuffer::Mapping M; M.BeginExpanded = BeginExpanded; diff --git a/clang/unittests/Tooling/Syntax/TokensTest.cpp b/clang/unittests/Tooling/Syntax/TokensTest.cpp --- a/clang/unittests/Tooling/Syntax/TokensTest.cpp +++ b/clang/unittests/Tooling/Syntax/TokensTest.cpp @@ -484,6 +484,42 @@ ['EMPTY'_9, 'EMPTY_FUNC'_10) => [''_0, ''_0) ['EMPTY_FUNC'_10, ''_18) => [''_0, ''_0) )"}, + // Baseline case, bugz: https://bugs.llvm.org/show_bug.cgi?id=45428 + {R"cpp( + #define NUM 42 + #define M2(a1,...) {__VA_ARGS__;} + #define M1(a2,...) M2(a2,__VA_ARGS__) + void foo(void) { M1(0, NUM); } + )cpp", + R"(expanded tokens: + void foo ( void ) { { 42 ; } ; } +file './input.cpp' + spelled tokens: + # define NUM 42 # define M2 ( a1 , ... ) { __VA_ARGS__ ; } # define M1 ( a2 , ... ) M2 ( a2 , __VA_ARGS__ ) void foo ( void ) { M1 ( 0 , NUM ) ; } + mappings: + ['#'_0, 'void'_30) => ['void'_0, 'void'_0) + ['M1'_36, ';'_42) => ['{'_6, ';'_10) +)"}, + // Reproducer, bugz: https://bugs.llvm.org/show_bug.cgi?id=45428. + // Causes mapping miss when invoking tryConsumeSpelledUntil + {R"cpp( + #define NUM 42 + #define M2(a1,...) {__VA_ARGS__;} + #define M1(a2,...) M2(a2,__VA_ARGS__) + #define M0 M1 + void foo(void) { M0(0, NUM); } + )cpp", + R"(expanded tokens: + void foo ( void ) { { 42 ; } ; } +file './input.cpp' + spelled tokens: + # define NUM 42 # define M2 ( a1 , ... ) { __VA_ARGS__ ; } # define M1 ( a2 , ... ) M2 ( a2 , __VA_ARGS__ ) # define M0 M1 void foo ( void ) { M0 ( 0 , NUM ) ; } + mappings: + ['#'_0, 'void'_34) => ['void'_0, 'void'_0) + ['M0'_40, 'NUM'_44) => ['{'_6, ';'_10) + ['NUM'_44, ')'_45) => [';'_10, ';'_10) + [')'_45, ';'_46) => [';'_10, ';'_10) +)"}, // File ends with a macro replacement. {R"cpp( #define FOO 10+10;