llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Zahira Ammarguellat (zahiraam)

<details>
<summary>Changes</summary>

In` C23`, `auto &lt;typedef-name&gt; &lt;var&gt;;` was misparsed as auto 
type-inference on  the `typedef`, then errored on the missing initializer. 
Pre-C23 clang accepts it as a declaration of `&lt;var&gt;` with the typedef's 
type (`auto` used as storage-class with an explicit type-name).

```
typedef int x;
{ auto x y; }   // valid: declares `y` of type `x`
```
  
Fix for https://github.com/llvm/llvm-project/issues/164930.



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


2 Files Affected:

- (modified) clang/lib/Parse/ParseDecl.cpp (+28) 
- (modified) clang/test/C/C23/n3007.c (+18) 


``````````diff
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index a4bdec00ca80a..ad0836a94a17b 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4119,6 +4119,25 @@ void Parser::ParseDeclarationSpecifiers(
       break;
     case tok::kw_auto:
       if (getLangOpts().CPlusPlus11 || getLangOpts().C23) {
+        // FIXME: In C++, `auto` as a storage-class specifier is a
+        // deprecated extension. This lookahead runs for C only.
+        auto IsTypedefName = [&](const Token &T) {
+          if (!T.is(tok::identifier))
+            return false;
+          IdentifierInfo *II = T.getIdentifierInfo();
+          if (!II)
+            return false;
+          // Use a raw suppressed lookup (rather than Sema::getTypeName) to
+          // avoid emitting deprecation/availability diagnostics on the
+          // typedef during this speculative peek — the real parse will look
+          // the name up again and emit them at the right time.
+          LookupResult R(Actions, II, T.getLocation(),
+                         Sema::LookupOrdinaryName);
+          Actions.LookupName(R, getCurScope(),
+                             /*AllowBuiltinCreation=*/false);
+          R.suppressDiagnostics();
+          return R.isSingleResult() && isa<TypeDecl>(R.getFoundDecl());
+        };
         auto MayBeTypeSpecifier = [&]() {
           // In pre-C23 C, auto can be used as a storage-class specifier.
           // C23 removes auto from the storage-class specifiers and repurposes
@@ -4133,6 +4152,15 @@ void Parser::ParseDeclarationSpecifiers(
             if (isKnownToBeTypeSpecifier(T))
               return true;
 
+            // C23: a bare identifier that names a typedef is a type
+            // specifier here, so `auto typedefName varName;` should be
+            // parsed with `auto` as the storage-class specifier — not as
+            // type inference. Without this check the parser would consume
+            // `auto` as type-inference and then error on the missing
+            // initializer for what it thinks is `typedefName`.
+            if (getLangOpts().C23 && IsTypedefName(T))
+              return true;
+
             if (getLangOpts().C23 && isTypeSpecifierQualifier(T))
               ++I;
             else
diff --git a/clang/test/C/C23/n3007.c b/clang/test/C/C23/n3007.c
index a881b89443462..e2aaee1cd08b9 100644
--- a/clang/test/C/C23/n3007.c
+++ b/clang/test/C/C23/n3007.c
@@ -3,6 +3,7 @@
 /* WG14 N3007: Yes
  * Type Inference for object definitions
  */
+
 void test_auto_int(void) {
   auto int auto_int = 12;
 }
@@ -209,3 +210,20 @@ void test_macros(int in_int) {
   _Static_assert(_Generic(c, int : 1));
   _Static_assert(_Generic(result, int : 1));
 }
+
+// `auto <typedef-name> <var>;` should parse as a declaration of <var> with
+// type <typedef-name> (auto used as storage-class in C23 with an explicit
+// type-name), not as inferred type deduction on the typedef.
+void test_auto_typedef(void) {
+  typedef int T;
+  {
+    auto T at_local;
+    at_local = 42;
+    _Static_assert(_Generic(at_local, int : 1));
+  }
+  {
+    // Also works with qualifiers.
+    const auto T at_const = 1;
+    _Static_assert(_Generic(&at_const, const int * : 1));
+  }
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/224019
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to