[clang] [Clang][Parse] Fix assertion when annotating a failed decltype-specifier (PR #211221)

Akash Agrawal via cfe-commits cfe-commits at lists.llvm.org
Sun Jul 26 22:14:26 PDT 2026


================
@@ -1136,6 +1136,20 @@ void Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,
   // make sure we have a token we can turn into an annotation token
   if (PP.isBacktrackEnabled()) {
     PP.RevertCachedTokens(1);
+    if (DS.getTypeSpecType() == TST_error && PP.hasCachedTokenLocation()) {
----------------
akashagrwl wrote:

I tried dropping it and it actually breaks things — annotating turns out to be load-bearing.

The catch is that TST_error covers two cases: `decltype `with no  (our crash), and a valid `decltype(...) `with a bad inner expression like `decltype(undeclared)`. The second one already consumed a real (...) range, and the annotation is what lets the caller keep treating it as a type. If we bail early, the caller re-sees raw tokens and spews follow-on errors — e.g.` enum G : decltype`; in` p8-0x.cpp` goes from one clean diagnostic to a whole cascade (~40 tests regress this way).

So instead of dropping, I fix the stale EndLoc where it's actually used. This is the same thing the sibling `AnnotateExistingIndexedTypeNamePack` already does on a failed parse `(EndLoc = PP.getLastCachedTokenLocation())`. The only extra bit is a `hasCachedTokenLocation()` guard, because unlike the pack path, decltype can reach here with an empty cache — e.g. via a macro `(#define ID(X) X / extern int ID(decltype);`, see gh114815.cpp) — and without the guard `getLastCachedTokenLocation() `asserts.

https://github.com/llvm/llvm-project/pull/211221


More information about the cfe-commits mailing list