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
  • [PATCH] D91821: F... Faisal Vali via Phabricator via cfe-commits

Reply via email to