Skip to content

Commit 46b862a

Browse files
committed
[clang] Reject 'auto' storage class with type specifier in C++
Previously, clang allowed 'auto int x = 1;' in C++ as an extension (for C compatibility), emitting only a warning. This was confusing since 'auto' in C++11+ is a type specifier, not a storage class. This patch: - Adds a new error diagnostic 'err_auto_type_specifier' - Updates the parser to emit an error (instead of warning) when 'auto' is used as a storage class with a type specifier in C++ mode - Preserves C23 behavior where 'auto int' is valid - Adds comprehensive tests Fixes #164273 Signed-off-by: Osama Abdelkader <[email protected]>
1 parent 269f264 commit 46b862a

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,8 @@ def err_requires_clause_on_declarator_not_declaring_a_function : Error<
399399
"trailing requires clause can only be used when declaring a function">;
400400
def err_requires_clause_inside_parens : Error<
401401
"trailing requires clause should be placed outside parentheses">;
402+
def err_auto_type_specifier : Error<
403+
"'auto' cannot be combined with a type specifier in C++">;
402404
def ext_auto_storage_class : ExtWarn<
403405
"'auto' storage class specifier is not permitted in C++11, and will not "
404406
"be supported in future releases">, InGroup<DiagGroup<"auto-storage-class">>;

clang/lib/Parse/ParseDecl.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4095,11 +4095,17 @@ void Parser::ParseDeclarationSpecifiers(
40954095
case tok::kw_auto:
40964096
if (getLangOpts().CPlusPlus11 || getLangOpts().C23) {
40974097
if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
4098-
isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
4099-
PrevSpec, DiagID, Policy);
4100-
if (!isInvalid && !getLangOpts().C23)
4101-
Diag(Tok, diag::ext_auto_storage_class)
4102-
<< FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
4098+
// In C++ (not C23), 'auto' cannot be combined with a type specifier.
4099+
if (getLangOpts().CPlusPlus && !getLangOpts().C23) {
4100+
isInvalid = true;
4101+
if (!PrevSpec)
4102+
PrevSpec = "";
4103+
DiagID = diag::err_auto_type_specifier;
4104+
} else {
4105+
// C23 allows 'auto' as storage class with type specifier.
4106+
isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
4107+
PrevSpec, DiagID, Policy);
4108+
}
41034109
} else
41044110
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
41054111
DiagID, Policy);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s
3+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
4+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
5+
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++23 %s
6+
// RUN: %clang_cc1 -fsyntax-only -verify=c23 -std=c23 %s
7+
8+
// Test that 'auto' cannot be combined with a type specifier in C++.
9+
void f() {
10+
auto int x = 1; // expected-error {{'auto' cannot be combined with a type specifier in C++}}
11+
auto char c = 'a'; // expected-error {{'auto' cannot be combined with a type specifier in C++}}
12+
auto float f = 1.0f; // expected-error {{'auto' cannot be combined with a type specifier in C++}}
13+
auto double d = 1.0; // expected-error {{'auto' cannot be combined with a type specifier in C++}}
14+
auto long l = 1L; // expected-error {{'auto' cannot be combined with a type specifier in C++}}
15+
}
16+
17+
// Test that 'auto' as a storage class with type specifier is still allowed in C23.
18+
void g() {
19+
auto int x = 1; // c23-no-diagnostics
20+
auto char c = 'a'; // c23-no-diagnostics
21+
}
22+
23+
// Test that regular 'auto' (type deduction) still works in C++.
24+
void h() {
25+
auto x = 1; // expected-no-diagnostics
26+
auto y = 2.0; // expected-no-diagnostics
27+
auto z = 'c'; // expected-no-diagnostics
28+
}
29+

0 commit comments

Comments
 (0)