[llvm-branch-commits] [clang] 967834a - [clang][c23] Avoid assertion on an invalid static constexpr variable (#175927)

Cullen Rhodes via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Jan 15 01:47:47 PST 2026


Author: Mariya Podchishchaeva
Date: 2026-01-15T09:47:39Z
New Revision: 967834a63c0f2c35f974c202aaf0157be253dfc5

URL: https://github.com/llvm/llvm-project/commit/967834a63c0f2c35f974c202aaf0157be253dfc5
DIFF: https://github.com/llvm/llvm-project/commit/967834a63c0f2c35f974c202aaf0157be253dfc5.diff

LOG: [clang][c23] Avoid assertion on an invalid static constexpr variable (#175927)

In C static variables should have constant expressions in initializers
so we were checking this twice for constexpr variables and failing with
an assertion that was makes sure we don't do it.
This patch postpones the check just like it is done for file
scope constexpr variables in C already.

Fixes https://github.com/llvm/llvm-project/issues/173605

(cherry picked from commit 5b0270cb72f707f55e2ff5e97fc938afb3b81053)

Added: 
    

Modified: 
    clang/lib/Sema/SemaDecl.cpp
    clang/test/Sema/constexpr.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f9580b34aaec6..d67220a2f170d 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -14156,7 +14156,10 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
     // C99 6.7.8p4: All the expressions in an initializer for an object that has
     // static storage duration shall be constant expressions or string literals.
     } else if (VDecl->getStorageClass() == SC_Static) {
-      CheckForConstantInitializer(Init);
+      // Avoid evaluating the initializer twice for constexpr variables. It will
+      // be evaluated later.
+      if (!VDecl->isConstexpr())
+        CheckForConstantInitializer(Init);
 
       // C89 is stricter than C99 for aggregate initializers.
       // C89 6.5.7p3: All the expressions [...] in an initializer list

diff  --git a/clang/test/Sema/constexpr.c b/clang/test/Sema/constexpr.c
index b5b62863cfdad..ae01c71e09b06 100644
--- a/clang/test/Sema/constexpr.c
+++ b/clang/test/Sema/constexpr.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c23 -verify -triple x86_64 -pedantic -Wno-conversion -Wno-constant-conversion -Wno-div-by-zero %s
+// RUN: %clang_cc1 -std=c23 -verify -triple x86_64 -pedantic -Wno-conversion -Wno-constant-conversion -Wno-div-by-zero -fexperimental-new-constant-interpreter %s
 
 // Check that constexpr only applies to variables.
 constexpr void f0() {} // expected-error {{'constexpr' can only be used in variable declarations}}
@@ -416,3 +417,10 @@ void gh173847_test() {
   constexpr double d_const = gh173847_double(2.0);             // expected-error {{constexpr variable 'd_const' must be initialized by a constant expression}}
   constexpr long double ld_const = gh173847_long_double(2.0L); // expected-error {{constexpr variable 'ld_const' must be initialized by a constant expression}}
 }
+
+int gh173605(int x) {
+  static constexpr int c = c; // expected-error {{constexpr variable 'c' must be initialized by a constant expression}}\
+                              // expected-note {{read of object outside its lifetime is not allowed in a constant expression}}
+  static int justincase = justincase; // expected-error {{initializer element is not a compile-time constant}}
+  return x;
+}


        


More information about the llvm-branch-commits mailing list