[clang] [clang] Reject 'auto' storage class with type specifier in C++ (PR #166004)

Tony Guillot via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 17 07:05:11 PDT 2026


================
@@ -3860,6 +3875,44 @@ void Parser::ParseDeclarationSpecifiers(
         goto DoneWithDeclSpec;
       }
 
+      // If 'auto' is set and this identifier is a type name, check if it's
+      // followed by declarator tokens (like '=', '(', '[', etc.). If so, this
+      // identifier is likely the variable name, not a type specifier, so we
+      // should stop parsing declaration specifiers.
+      // Also check for concept constraint syntax (C<T> auto param) where
+      // the identifier before 'auto' might be a concept, not a type conflict.
+      // Also check for template parameters (template<auto V>) and lambda
+      // parameters
+      // ([](auto c)) where the identifier is a parameter name, not a type
+      // conflict.
+      if (DS.getTypeSpecType() == DeclSpec::TST_auto && TypeRep) {
+        // Check if the next token indicates this is a declarator
+        Token Next = NextToken();
+        if (Next.isOneOf(tok::equal, tok::l_paren, tok::l_square, tok::amp,
+                         tok::ampamp, tok::star, tok::coloncolon, tok::comma,
+                         tok::semi, tok::colon, tok::greater, tok::r_paren,
+                         tok::arrow)) {
+          // This identifier is likely the variable/parameter name, stop parsing
+          // decl specifiers. Note: ':' is for range-based for loops:
+          // for (auto Arg: x).
+          // Note: '>' is for template parameters: template<auto V>
+          // Note: ')' is for function/lambda parameters: [](auto c)
+          // Note: '->' is for lambda return types: [](auto c) -> int
+          goto DoneWithDeclSpec;
+        }
+        // Check for concept constraint syntax: C<T> auto param)
+        // If the identifier is followed by 'auto' and then an identifier that's
+        // followed by ')', this might be concept syntax, not a type conflict.
+        if (Next.is(tok::identifier)) {
+          // Look ahead to see if this is followed by ')' (function parameter)
+          Token AfterNext = GetLookAheadToken(2);
+          if (AfterNext.is(tok::r_paren)) {
+            // This might be concept constraint syntax, skip conflict detection
+            goto DoneWithDeclSpec;
+          }
+        }
+      }
+
----------------
to268 wrote:

I would rather move this part in Sema if possible.

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


More information about the cfe-commits mailing list