[PATCH] D91821: Fix PR42049 - Crash when parsing bad decltype use within template argument list after name assumed to be a function template

Faisal Vali via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 19 13:42:30 PST 2020


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);
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D91821.306521.patch
Type: text/x-patch
Size: 1583 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20201119/45e1ae03/attachment-0001.bin>


More information about the cfe-commits mailing list