[clang] [clang] Reject 'auto' storage class with type specifier in C++ (PR #166004)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Nov 1 10:58:10 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Osama Abdelkader (osamakader)
<details>
<summary>Changes</summary>
Fixes #<!-- -->164273
---
Full diff: https://github.com/llvm/llvm-project/pull/166004.diff
3 Files Affected:
- (modified) clang/include/clang/Basic/DiagnosticParseKinds.td (+2)
- (modified) clang/lib/Parse/ParseDecl.cpp (+11-5)
- (added) clang/test/Parser/cxx-auto-type-specifier.cpp (+29)
``````````diff
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index e5e071f43fa75..baf91b107b8c4 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -399,6 +399,8 @@ def err_requires_clause_on_declarator_not_declaring_a_function : Error<
"trailing requires clause can only be used when declaring a function">;
def err_requires_clause_inside_parens : Error<
"trailing requires clause should be placed outside parentheses">;
+def err_auto_type_specifier : Error<
+ "'auto' cannot be combined with a type specifier in C++">;
def ext_auto_storage_class : ExtWarn<
"'auto' storage class specifier is not permitted in C++11, and will not "
"be supported in future releases">, InGroup<DiagGroup<"auto-storage-class">>;
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 7e4a164e34eda..0044201b459b3 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4095,11 +4095,17 @@ void Parser::ParseDeclarationSpecifiers(
case tok::kw_auto:
if (getLangOpts().CPlusPlus11 || getLangOpts().C23) {
if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
- isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
- PrevSpec, DiagID, Policy);
- if (!isInvalid && !getLangOpts().C23)
- Diag(Tok, diag::ext_auto_storage_class)
- << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
+ // In C++ (not C23), 'auto' cannot be combined with a type specifier.
+ if (getLangOpts().CPlusPlus && !getLangOpts().C23) {
+ isInvalid = true;
+ if (!PrevSpec)
+ PrevSpec = "";
+ DiagID = diag::err_auto_type_specifier;
+ } else {
+ // C23 allows 'auto' as storage class with type specifier.
+ isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
+ PrevSpec, DiagID, Policy);
+ }
} else
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
DiagID, Policy);
diff --git a/clang/test/Parser/cxx-auto-type-specifier.cpp b/clang/test/Parser/cxx-auto-type-specifier.cpp
new file mode 100644
index 0000000000000..7a1291b08f7d3
--- /dev/null
+++ b/clang/test/Parser/cxx-auto-type-specifier.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++23 %s
+// RUN: %clang_cc1 -fsyntax-only -verify=c23 -std=c23 %s
+
+// Test that 'auto' cannot be combined with a type specifier in C++.
+void f() {
+ auto int x = 1; // expected-error {{'auto' cannot be combined with a type specifier in C++}}
+ auto char c = 'a'; // expected-error {{'auto' cannot be combined with a type specifier in C++}}
+ auto float f = 1.0f; // expected-error {{'auto' cannot be combined with a type specifier in C++}}
+ auto double d = 1.0; // expected-error {{'auto' cannot be combined with a type specifier in C++}}
+ auto long l = 1L; // expected-error {{'auto' cannot be combined with a type specifier in C++}}
+}
+
+// Test that 'auto' as a storage class with type specifier is still allowed in C23.
+void g() {
+ auto int x = 1; // c23-no-diagnostics
+ auto char c = 'a'; // c23-no-diagnostics
+}
+
+// Test that regular 'auto' (type deduction) still works in C++.
+void h() {
+ auto x = 1; // expected-no-diagnostics
+ auto y = 2.0; // expected-no-diagnostics
+ auto z = 'c'; // expected-no-diagnostics
+}
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/166004
More information about the cfe-commits
mailing list