Skip to content

Conversation

@cor3ntin
Copy link
Contributor

We would try to exact an annotated token before checking if it was valid, leading to a crash when decltype was the only token that was parsed (which can happen in the absense of opening paren)

Fixes #114815

We would try to exact an annotated token before checking
if it was valid, leading to a crash when `decltype` was the only
token that was parsed (which can happen in the absense of opening
paren)

Fixes llvm#114815
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jul 15, 2025
@llvmbot
Copy link
Member

llvmbot commented Jul 15, 2025

@llvm/pr-subscribers-clang

Author: Corentin Jabot (cor3ntin)

Changes

We would try to exact an annotated token before checking if it was valid, leading to a crash when decltype was the only token that was parsed (which can happen in the absense of opening paren)

Fixes #114815


Full diff: https://github.com/llvm/llvm-project/pull/148798.diff

2 Files Affected:

  • (modified) clang/lib/Parse/ParseDeclCXX.cpp (+3-3)
  • (added) clang/test/Parser/gh114815.cpp (+6)
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 59e6e0af4b5b0..5bdc13d75a9e1 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1132,14 +1132,14 @@ void Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,
                                                SourceLocation EndLoc) {
   // make sure we have a token we can turn into an annotation token
   if (PP.isBacktrackEnabled()) {
-    PP.RevertCachedTokens(1);
-    if (DS.getTypeSpecType() == TST_error) {
+    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.RevertCachedTokens(1);
   } else
     PP.EnterToken(Tok, /*IsReinject*/ true);
 
diff --git a/clang/test/Parser/gh114815.cpp b/clang/test/Parser/gh114815.cpp
new file mode 100644
index 0000000000000..6a89384e9e66d
--- /dev/null
+++ b/clang/test/Parser/gh114815.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -verify %s -std=c++11 -fsyntax-only
+
+#define ID(X) X
+extern int ID(decltype);
+// expected-error@-1 {{expected '(' after 'decltype'}} \
+// expected-error@-1 {{expected unqualified-id}}

@cor3ntin cor3ntin merged commit 55f1b91 into llvm:main Jul 15, 2025
9 checks passed
Copy link
Collaborator

@shafik shafik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No release note?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[clang] Assertion `CachedLexPos != 0' failed.

5 participants