faisalv created this revision. faisalv added a reviewer: rsmith. faisalv added a project: clang. Herald added a subscriber: cfe-commits. faisalv requested review of this revision.
https://bugs.llvm.org/show_bug.cgi?id=42049 Currently clang, in the following code, when tentatively parsing the template-argument-list recognizes the error, and skips till the semi-colon. But when annotating the broken decltype specifier token (in an effort to backtrack gracefully and continue parsing), it appears we should include all the cached tokens that were skipped until the sem-colon as an annotated subset of our annot_decltype token. Not doing so results in a book-keeping assertion failure. void f() { g<decltype>(); } This situation did not seem to arise prior to https://github.com/llvm/llvm-project/commit/b23c5e8c3df850177449268c5ca7dbf986157525 - which implements assumption of names as function templates even if no function with that name is found. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D91821 Files: clang/lib/Parse/ParseDeclCXX.cpp clang/test/Parser/PR42049.cpp Index: clang/test/Parser/PR42049.cpp =================================================================== --- /dev/null +++ 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<decltype>(); // expected-error 2 {{expected}} expected-note {{to match}} + g2<decltype x; // expected-error 2{{expected}} expected-note {{to match}} +} + +template<class T> void f2() { + g<decltype>(); // expected-error 2 {{expected}} expected-note {{to match}} + g2<decltype x; // expected-error 2{{expected}} expected-note {{to match}} +} + Index: clang/lib/Parse/ParseDeclCXX.cpp =================================================================== --- clang/lib/Parse/ParseDeclCXX.cpp +++ clang/lib/Parse/ParseDeclCXX.cpp @@ -1045,8 +1045,16 @@ SourceLocation StartLoc, SourceLocation EndLoc) { // make sure we have a token we can turn into an annotation token - if (PP.isBacktrackEnabled()) + 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(); + } + } else PP.EnterToken(Tok, /*IsReinject*/true);
Index: clang/test/Parser/PR42049.cpp =================================================================== --- /dev/null +++ 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<decltype>(); // expected-error 2 {{expected}} expected-note {{to match}} + g2<decltype x; // expected-error 2{{expected}} expected-note {{to match}} +} + +template<class T> void f2() { + g<decltype>(); // expected-error 2 {{expected}} expected-note {{to match}} + g2<decltype x; // expected-error 2{{expected}} expected-note {{to match}} +} + Index: clang/lib/Parse/ParseDeclCXX.cpp =================================================================== --- clang/lib/Parse/ParseDeclCXX.cpp +++ clang/lib/Parse/ParseDeclCXX.cpp @@ -1045,8 +1045,16 @@ SourceLocation StartLoc, SourceLocation EndLoc) { // make sure we have a token we can turn into an annotation token - if (PP.isBacktrackEnabled()) + 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(); + } + } else PP.EnterToken(Tok, /*IsReinject*/true);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits