[clang] [Clang] disallow constexpr with auto and explicit type in C23 (PR #163469)

Oleksandr T. via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 16 17:16:14 PDT 2025


https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/163469

>From 3856379ddbb59c6dcd813765571a67f635034a3c Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Wed, 15 Oct 2025 01:42:15 +0300
Subject: [PATCH 1/5] [Clang] disallow constexpr with auto and explicit type in
 C23

---
 clang/docs/ReleaseNotes.rst  | 2 ++
 clang/lib/Sema/DeclSpec.cpp  | 2 +-
 clang/test/Parser/c2x-auto.c | 2 ++
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index edb872c1f388d..de745e54a0cbd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -269,6 +269,8 @@ Non-comprehensive list of changes in this release
   allocation functions with a token ID can be enabled via the
   ``-fsanitize=alloc-token`` flag.
 
+- Clang now rejects the invalid use of ``constexpr`` with ``auto`` and an explicit type. (#GH163090)
+
 New Compiler Flags
 ------------------
 - New option ``-fno-sanitize-debug-trap-reasons`` added to disable emitting trap reasons into the debug info when compiling with trapping UBSan (e.g. ``-fsanitize-trap=undefined``).
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index 184d31ecd1e40..482cb1fe703fe 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -1369,7 +1369,7 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
 
   if (S.getLangOpts().C23 &&
       getConstexprSpecifier() == ConstexprSpecKind::Constexpr &&
-      StorageClassSpec == SCS_extern) {
+      (StorageClassSpec == SCS_extern || StorageClassSpec == SCS_auto)) {
     S.Diag(ConstexprLoc, diag::err_invalid_decl_spec_combination)
         << DeclSpec::getSpecifierName(getStorageClassSpec())
         << SourceRange(getStorageClassSpecLoc());
diff --git a/clang/test/Parser/c2x-auto.c b/clang/test/Parser/c2x-auto.c
index b878a5b7c42d4..b33b267841132 100644
--- a/clang/test/Parser/c2x-auto.c
+++ b/clang/test/Parser/c2x-auto.c
@@ -62,6 +62,8 @@ auto basic_usage(auto auto) {   // c23-error {{'auto' not allowed in function pr
 
   int auto_cxx_decl = auto(0);  // expected-error {{expected expression}}
 
+  constexpr auto int x = 0; // c23-error {{cannot combine with previous 'auto' declaration specifier}} \
+                               c17-error {{use of undeclared identifier 'constexpr'}}
   return c;
 }
 

>From 6bbca07057a9824badb0d04c6d7dc55b703378ed Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Wed, 15 Oct 2025 14:36:37 +0300
Subject: [PATCH 2/5] add additional test

---
 clang/test/Parser/c2x-auto.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/clang/test/Parser/c2x-auto.c b/clang/test/Parser/c2x-auto.c
index b33b267841132..e8e36df096e08 100644
--- a/clang/test/Parser/c2x-auto.c
+++ b/clang/test/Parser/c2x-auto.c
@@ -64,6 +64,10 @@ auto basic_usage(auto auto) {   // c23-error {{'auto' not allowed in function pr
 
   constexpr auto int x = 0; // c23-error {{cannot combine with previous 'auto' declaration specifier}} \
                                c17-error {{use of undeclared identifier 'constexpr'}}
+
+  constexpr int auto y = 0; // c23-error {{cannot combine with previous 'int' declaration specifier}} \
+                               c17-error {{use of undeclared identifier 'constexpr'}}
+
   return c;
 }
 

>From a6b55edcb4e28a774b604ba652589604cd527f6d Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Wed, 15 Oct 2025 14:42:11 +0300
Subject: [PATCH 3/5] update release notes

---
 clang/docs/ReleaseNotes.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b4620dff8e9fe..4f7a72cc62985 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -271,7 +271,7 @@ Non-comprehensive list of changes in this release
   allocation functions with a token ID can be enabled via the
   ``-fsanitize=alloc-token`` flag.
 
-- Clang now rejects the invalid use of ``constexpr`` with ``auto`` and an explicit type. (#GH163090)
+- Clang now rejects the invalid use of ``constexpr`` with ``auto`` and an explicit type in C. (#GH163090)
 
 New Compiler Flags
 ------------------

>From 9bbce08f30878ed426f6e5cbd05d278234692e5a Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Wed, 15 Oct 2025 23:28:31 +0300
Subject: [PATCH 4/5] update tests

---
 clang/test/Parser/c2x-auto.c | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/clang/test/Parser/c2x-auto.c b/clang/test/Parser/c2x-auto.c
index e8e36df096e08..7f80b0717ab25 100644
--- a/clang/test/Parser/c2x-auto.c
+++ b/clang/test/Parser/c2x-auto.c
@@ -62,12 +62,6 @@ auto basic_usage(auto auto) {   // c23-error {{'auto' not allowed in function pr
 
   int auto_cxx_decl = auto(0);  // expected-error {{expected expression}}
 
-  constexpr auto int x = 0; // c23-error {{cannot combine with previous 'auto' declaration specifier}} \
-                               c17-error {{use of undeclared identifier 'constexpr'}}
-
-  constexpr int auto y = 0; // c23-error {{cannot combine with previous 'int' declaration specifier}} \
-                               c17-error {{use of undeclared identifier 'constexpr'}}
-
   return c;
 }
 
@@ -136,3 +130,30 @@ void atomic(void) {
 void attributes(void) {
   auto ident [[clang::annotate("this works")]] = 12;  // c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
 }
+
+/** GH163090 */
+constexpr auto int a1 = 0; // c23-error {{illegal storage class on file-scoped variable}} \
+                              c23-error {{cannot combine with previous 'auto' declaration specifier}} \
+                              c17-error {{illegal storage class on file-scoped variable}} \
+                              c17-error {{unknown type name 'constexpr'}}
+
+constexpr int auto a2 = 0; // c23-error {{cannot combine with previous 'int' declaration specifier}} \
+                              c17-error {{illegal storage class on file-scoped variable}} \
+                              c17-error {{unknown type name 'constexpr'}}
+
+auto int b1 = 0; // c23-error {{illegal storage class on file-scoped variable}} \
+                    c17-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() {
+  constexpr auto int c1 = 0; // c23-error {{cannot combine with previous 'auto' declaration specifier}} \
+                                c17-error {{use of undeclared identifier 'constexpr'}}
+
+  constexpr int auto c2 = 0; // c23-error {{cannot combine with previous 'int' declaration specifier}} \
+                                c17-error {{use of undeclared identifier 'constexpr'}}
+
+  auto int d1 = 0;
+  int auto d2 = 0; // c23-error {{cannot combine with previous 'int' declaration specifier}}
+}

>From 9e9f328bb7bd9b1b8a24c27a0307f447ff7e4f5a Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Thu, 16 Oct 2025 12:52:01 +0300
Subject: [PATCH 5/5] add check type specifier

---
 clang/lib/Sema/DeclSpec.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index 482cb1fe703fe..9da3d0d2ef599 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -1369,6 +1369,7 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
 
   if (S.getLangOpts().C23 &&
       getConstexprSpecifier() == ConstexprSpecKind::Constexpr &&
+      getTypeSpecType() != TST_unspecified &&
       (StorageClassSpec == SCS_extern || StorageClassSpec == SCS_auto)) {
     S.Diag(ConstexprLoc, diag::err_invalid_decl_spec_combination)
         << DeclSpec::getSpecifierName(getStorageClassSpec())



More information about the cfe-commits mailing list