[clang] [Clang] prevent incorrect rejection of auto with reordered declaration specifiers in C23 (PR #177865)
Oleksandr Tarasiuk via cfe-commits
cfe-commits at lists.llvm.org
Sun Jan 25 09:51:52 PST 2026
https://github.com/a-tarasyuk created https://github.com/llvm/llvm-project/pull/177865
Fixes #164121
---
This patch addresses the issue where `auto` was incorrectly rejected with reordered declaration specifiers in C23.
>From 886c342fcf9a2a84929f6fb3eb51ea74de5c6b83 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Sun, 25 Jan 2026 19:05:45 +0200
Subject: [PATCH] [Clang] prevent incorrect rejection of auto with reordered
declaration specifiers in C23
---
clang/docs/ReleaseNotes.rst | 1 +
clang/lib/Parse/ParseDecl.cpp | 14 +++++++++++++-
clang/test/Parser/c2x-auto.c | 24 +++++++++++++++++++++++-
3 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a734804865c57..47e578448e1e8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -169,6 +169,7 @@ Bug Fixes in This Version
-------------------------
- Fix lifetime extension of temporaries in for-range-initializers in templates. (#GH165182)
+- Fixed incorrect rejection of ``auto`` with reordered declaration specifiers in C23. (#GH164121)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index f8c49646fcf3f..404f0a312b8bf 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4093,7 +4093,19 @@ void Parser::ParseDeclarationSpecifiers(
break;
case tok::kw_auto:
if (getLangOpts().CPlusPlus11 || getLangOpts().C23) {
- if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
+ auto IsTypeSpecifier = [&]() {
+ if (DS.getTypeSpecWidth() != TypeSpecifierWidth::Unspecified)
+ return true;
+
+ unsigned I = 1;
+ while (GetLookAheadToken(I).isOneOf(tok::kw_const, tok::kw_volatile,
+ tok::kw_restrict))
+ ++I;
+
+ return isKnownToBeTypeSpecifier(GetLookAheadToken(I));
+ };
+
+ if (IsTypeSpecifier()) {
isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
PrevSpec, DiagID, Policy);
if (!isInvalid && !getLangOpts().C23)
diff --git a/clang/test/Parser/c2x-auto.c b/clang/test/Parser/c2x-auto.c
index 7f80b0717ab25..cee670bf7b952 100644
--- a/clang/test/Parser/c2x-auto.c
+++ b/clang/test/Parser/c2x-auto.c
@@ -147,7 +147,7 @@ auto int b1 = 0; // c23-error {{illegal storage class on file-scoped variable}}
int auto b2 = 0; // c23-error {{cannot combine with previous 'int' declaration specifier}} \
c17-error {{illegal storage class on file-scoped variable}}
-void f() {
+void t1() {
constexpr auto int c1 = 0; // c23-error {{cannot combine with previous 'auto' declaration specifier}} \
c17-error {{use of undeclared identifier 'constexpr'}}
@@ -157,3 +157,25 @@ void f() {
auto int d1 = 0;
int auto d2 = 0; // c23-error {{cannot combine with previous 'int' declaration specifier}}
}
+
+void t2() {
+ auto long long a1 = 0;
+ long auto long a2 = 0;
+ long long auto a3 = 0;
+
+ auto const long long b1 = 0;
+ long long const auto b2 = 0;
+ long long auto const b3 = 0;
+}
+
+void t3() {
+ const auto int a1 = 0;
+ auto const int a2 = 0;
+
+ volatile auto int a3 = 0;
+ auto volatile int a4 = 0;
+ auto volatile const int a5 = 0;
+ auto const volatile int a6 = 0;
+
+ auto restrict int a7 = 0; // expected-error {{restrict requires a pointer or reference ('int' is invalid}}
+}
More information about the cfe-commits
mailing list