[clang] [clang][bytecode] Fix wrong 'never produces a constant expression' diagnostic with static data members (PR #197881)

via cfe-commits cfe-commits at lists.llvm.org
Fri May 15 01:23:12 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

<details>
<summary>Changes</summary>

They can be initialized later, similar to extern variables.

---
Full diff: https://github.com/llvm/llvm-project/pull/197881.diff


3 Files Affected:

- (modified) clang/lib/AST/ByteCode/Interp.cpp (+9-2) 
- (modified) clang/lib/AST/ByteCode/Program.cpp (+9-12) 
- (modified) clang/test/AST/ByteCode/records.cpp (+10) 


``````````diff
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 0ac6d2f7737fc..f13720a961d68 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -660,8 +660,15 @@ bool DiagnoseUninitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
 
 bool DiagnoseUninitialized(InterpState &S, CodePtr OpPC, bool Extern,
                            const Block *B, AccessKinds AK) {
-  if (Extern && S.checkingPotentialConstantExpression())
-    return false;
+  if (S.checkingPotentialConstantExpression()) {
+    // Extern and static member declarations might be initialized later.
+    if (Extern)
+      return false;
+
+    if (const VarDecl *VD = B->getDescriptor()->asVarDecl();
+        VD && VD->isStaticDataMember())
+      return false;
+  }
 
   const Descriptor *Desc = B->getDescriptor();
 
diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp
index d49903e36d34a..c0cc17b6bcd04 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -214,18 +214,15 @@ UnsignedOrNone Program::createGlobal(const ValueDecl *VD, const Expr *Init) {
     }
 
     if (Redecl != VD) {
-      if (Block *RedeclBlock = Globals[Iter->second]->block();
-          RedeclBlock->isExtern()) {
-
-        // All pointers pointing to the previous extern decl now point to the
-        // new decl.
-        // A previous iteration might've already fixed up the pointers for this
-        // global.
-        if (RedeclBlock != NewGlobal->block())
-          RedeclBlock->movePointersTo(NewGlobal->block());
-
-        Globals[Iter->second] = NewGlobal;
-      }
+      Block *RedeclBlock = Globals[Iter->second]->block();
+      // All pointers pointing to the previous extern decl now point to the
+      // new decl.
+      // A previous iteration might've already fixed up the pointers for this
+      // global.
+      if (RedeclBlock != NewGlobal->block())
+        RedeclBlock->movePointersTo(NewGlobal->block());
+
+      Globals[Iter->second] = NewGlobal;
     }
     Iter->second = *Idx;
   }
diff --git a/clang/test/AST/ByteCode/records.cpp b/clang/test/AST/ByteCode/records.cpp
index 20ead8cffdd99..4cf532cd6e7c3 100644
--- a/clang/test/AST/ByteCode/records.cpp
+++ b/clang/test/AST/ByteCode/records.cpp
@@ -2011,3 +2011,13 @@ namespace RVOPtrIsExtern {
   }
   static_assert(test_all(), "");
 }
+
+namespace StaticMemberRedecl {
+  class S {
+    public:
+    static const int m;
+  };
+  constexpr int getM() { return S::m; }
+  const int S::m = 10;
+  static_assert(getM() == 10, "");
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/197881


More information about the cfe-commits mailing list