diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp --- a/clang/lib/Lex/TokenLexer.cpp +++ b/clang/lib/Lex/TokenLexer.cpp @@ -1020,8 +1020,17 @@ SourceLocation Limit = SM.getComposedLoc(BeginFID, SM.getFileIDSize(BeginFID)); Partition = All.take_while([&](const Token &T) { - return T.getLocation() >= BeginLoc && T.getLocation() < Limit && - NearLast(T.getLocation()); + // NOTE: the Limit is included! In general, all token locations + // should be within [BeginLoc, Limit) range. However, the clang + // lexer might inject extra tokens for error-recovery, and these extra + // tokens are not taken account in the expansion FileID size! + // + // Including Limit will not mischeck for across-file-id tokens + // because SourceManager allocates FileSize + 1 for each SLocEntry. + // + // See https://github.com/llvm/llvm-project/issues/60722. + return T.getLocation() >= BeginLoc && T.getLocation() <= Limit + && NearLast(T.getLocation()); }); } assert(!Partition.empty()); diff --git a/clang/test/Lexer/update_consecutive_macro_crash.cpp b/clang/test/Lexer/update_consecutive_macro_crash.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Lexer/update_consecutive_macro_crash.cpp @@ -0,0 +1,11 @@ +// RUN: %clang -cc1 -fsyntax-only -verify %s 2>&1 + +// https://github.com/llvm/llvm-project/issues/60722 +#define X(val2) Y(val2++) // expected-note {{macro 'X' defined here}} +#define Y(expression) expression ; + +void foo() { + X(int{,}); // expected-error {{too many arguments provided to function-like macro invocation}} \ + expected-error {{expected expression}} \ + expected-note {{parentheses are required around macro argument containing braced initializer list}} +}