https://github.com/akash-manna-sky updated 
https://github.com/llvm/llvm-project/pull/226386

>From 88b0e46d8779df2666a332d2a17072b44e32e76b Mon Sep 17 00:00:00 2001
From: Akash Manna <[email protected]>
Date: Fri, 25 Sep 2026 12:44:02 +0530
Subject: [PATCH] [clang][bytecode] Re-check the declaration before treating a
 block as weak

Sema drops an invalid weak attribute in FinalizeDeclaration, after the
initializer has already been evaluated. By then the interpreter has
created the global block and copied the weak flag into it, so later
reads keep failing even though the declaration is no longer weak. In
C++03 the ICE check sees the up-to-date declaration, accepts the
expression, and EvaluateKnownConstIntCheckOverflow asserts when the
interpreter refuses the load.

Make Block::isWeak() confirm with the declaration when the flag is set.

Fixes #156186
---
 clang/lib/AST/ByteCode/InterpBlock.cpp            | 10 ++++++++++
 clang/lib/AST/ByteCode/InterpBlock.h              |  2 +-
 clang/test/AST/ByteCode/weak-internal-linkage.cpp | 12 ++++++++++++
 3 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/AST/ByteCode/weak-internal-linkage.cpp

diff --git a/clang/lib/AST/ByteCode/InterpBlock.cpp 
b/clang/lib/AST/ByteCode/InterpBlock.cpp
index 888a660719590..6bd6d520e0037 100644
--- a/clang/lib/AST/ByteCode/InterpBlock.cpp
+++ b/clang/lib/AST/ByteCode/InterpBlock.cpp
@@ -55,6 +55,16 @@ void Block::removePointer(Pointer *P) {
 #endif
 }
 
+bool Block::isWeak() const {
+  if (!(AccessFlags & WeakFlag))
+    return false;
+
+  // Sema might have dropped the weak attribute after this block was created.
+  if (const ValueDecl *VD = Desc->asValueDecl())
+    return VD->isWeak();
+  return true;
+}
+
 void Block::cleanup() {
   if (Pointers == nullptr && !isDynamic() && isDead())
     (reinterpret_cast<DeadBlock *>(this + 1) - 1)->free();
diff --git a/clang/lib/AST/ByteCode/InterpBlock.h 
b/clang/lib/AST/ByteCode/InterpBlock.h
index 4d6a2ecf81321..469601eef9e28 100644
--- a/clang/lib/AST/ByteCode/InterpBlock.h
+++ b/clang/lib/AST/ByteCode/InterpBlock.h
@@ -79,7 +79,7 @@ class Block final {
   bool isStatic() const { return IsStatic; }
   /// Checks if the block is temporary.
   bool isTemporary() const { return Desc->IsTemporary; }
-  bool isWeak() const { return AccessFlags & WeakFlag; }
+  bool isWeak() const;
   bool isDynamic() const { return (DynAllocId != std::nullopt); }
   bool isDead() const { return AccessFlags & DeadFlag; }
   /// Returns the size of the block, including metadata.
diff --git a/clang/test/AST/ByteCode/weak-internal-linkage.cpp 
b/clang/test/AST/ByteCode/weak-internal-linkage.cpp
new file mode 100644
index 0000000000000..359f96d01788d
--- /dev/null
+++ b/clang/test/AST/ByteCode/weak-internal-linkage.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++03 -fexperimental-new-constant-interpreter 
-verify=expected,both %s
+// RUN: %clang_cc1 -std=c++03 -verify=ref,both %s
+// RUN: %clang_cc1 -std=c++20 -fexperimental-new-constant-interpreter 
-verify=expected,both %s
+// RUN: %clang_cc1 -std=c++20 -verify=ref,both %s
+
+/// The weak attribute is dropped after the initializer has been evaluated.
+__attribute__((weak)) const unsigned int test10_bound = 10; // both-error 
{{weak declaration cannot have internal linkage}}
+char test10_global[test10_bound];
+void test10(void) {
+  char test10_local[test10_bound] = "help";
+}
+int test10_size_check[sizeof(test10_global) == 10 ? 1 : -1];

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to