diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1048,11 +1048,15 @@ if (PP.isBacktrackEnabled()) { PP.RevertCachedTokens(1); if (DS.getTypeSpecType() == TST_error) { - // We encountered an error in parsing 'decltype(...)' so lets annotate all - // the tokens in the backtracking cache - that we likely had to skip over - // to get to a token that allows us to resume parsing, such as a - // semi-colon. - EndLoc = PP.getLastCachedTokenLocation(); + // We encountered an error in parsing 'decltype(...)' so lets revert + // the tokens (that we likely had to skip over to get to a stop token such + // as a semi-colon) in the backtracking cache to the EndLoc of where we + // think the decltype specifier tokens should have ended. Since these + // tokens are in the same token cache, their SourceLocations must have the + // same FileID and so should have well defined behavior when comparing. + assert(EndLoc <= PP.getLastCachedTokenLocation()); + while (EndLoc != PP.getLastCachedTokenLocation()) + PP.RevertCachedTokens(1); } } else diff --git a/clang/test/Parser/PR42049.cpp b/clang/test/Parser/PR42049.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Parser/PR42049.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// https://bugs.llvm.org/show_bug.cgi?id=42049 + +void f() { + g(); // expected-error {{use of undeclared identifier}} expected-error {{expected}} + g2 void f2() { + g(); // expected-error {{use of undeclared identifier}} expected-error {{expected}} + g2