Author: Timm Baeder
Date: 2025-08-19T10:54:33+02:00
New Revision: fb8ee3adb63c3556d5b77249b876dcd55c2cfe5d

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

LOG: [clang][bytecode] Move pointers from extern globals to new decls (#154273)

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/InterpBlock.h
    clang/lib/AST/ByteCode/Pointer.h
    clang/lib/AST/ByteCode/Program.cpp
    clang/test/AST/ByteCode/literals.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/InterpBlock.h 
b/clang/lib/AST/ByteCode/InterpBlock.h
index 1043fa0c55f32..ea9f44c38842e 100644
--- a/clang/lib/AST/ByteCode/InterpBlock.h
+++ b/clang/lib/AST/ByteCode/InterpBlock.h
@@ -149,6 +149,7 @@ class Block final {
   friend class DeadBlock;
   friend class InterpState;
   friend class DynamicAllocator;
+  friend class Program;
 
   Block(unsigned EvalID, const Descriptor *Desc, bool IsExtern, bool IsStatic,
         bool IsWeak, bool IsDummy, bool IsDead)

diff  --git a/clang/lib/AST/ByteCode/Pointer.h 
b/clang/lib/AST/ByteCode/Pointer.h
index 1dcdc0424801d..27659d7eeaf09 100644
--- a/clang/lib/AST/ByteCode/Pointer.h
+++ b/clang/lib/AST/ByteCode/Pointer.h
@@ -804,6 +804,7 @@ class Pointer {
   friend class InterpState;
   friend struct InitMap;
   friend class DynamicAllocator;
+  friend class Program;
 
   /// Returns the embedded descriptor preceding a field.
   InlineDescriptor *getInlineDesc() const {

diff  --git a/clang/lib/AST/ByteCode/Program.cpp 
b/clang/lib/AST/ByteCode/Program.cpp
index 749ae2510612c..755e5de4c02e2 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -213,19 +213,32 @@ std::optional<unsigned> Program::createGlobal(const 
ValueDecl *VD,
 
   // Register all previous declarations as well. For extern blocks, just 
replace
   // the index with the new variable.
-  if (auto Idx =
-          createGlobal(VD, VD->getType(), IsStatic, IsExtern, IsWeak, Init)) {
-    for (const Decl *P = VD; P; P = P->getPreviousDecl()) {
-      unsigned &PIdx = GlobalIndices[P];
-      if (P != VD) {
-        if (Globals[PIdx]->block()->isExtern())
-          Globals[PIdx] = Globals[*Idx];
+  std::optional<unsigned> Idx =
+      createGlobal(VD, VD->getType(), IsStatic, IsExtern, IsWeak, Init);
+  if (!Idx)
+    return std::nullopt;
+
+  Global *NewGlobal = Globals[*Idx];
+  for (const Decl *Redecl : VD->redecls()) {
+    unsigned &PIdx = GlobalIndices[Redecl];
+    if (Redecl != VD) {
+      if (Block *RedeclBlock = Globals[PIdx]->block();
+          RedeclBlock->isExtern()) {
+        Globals[PIdx] = NewGlobal;
+        // All pointers pointing to the previous extern decl now point to the
+        // new decl.
+        for (Pointer *Ptr = RedeclBlock->Pointers; Ptr;
+             Ptr = Ptr->PointeeStorage.BS.Next) {
+          RedeclBlock->removePointer(Ptr);
+          Ptr->PointeeStorage.BS.Pointee = NewGlobal->block();
+          NewGlobal->block()->addPointer(Ptr);
+        }
       }
-      PIdx = *Idx;
     }
-    return *Idx;
+    PIdx = *Idx;
   }
-  return std::nullopt;
+
+  return *Idx;
 }
 
 std::optional<unsigned> Program::createGlobal(const Expr *E) {
@@ -264,7 +277,7 @@ std::optional<unsigned> Program::createGlobal(const DeclTy 
&D, QualType Ty,
       Ctx.getEvalID(), getCurrentDecl(), Desc, IsStatic, IsExtern, IsWeak);
   G->block()->invokeCtor();
 
-  // Initialize InlineDescriptor fields.
+  // Initialize GlobalInlineDescriptor fields.
   auto *GD = new (G->block()->rawData()) GlobalInlineDescriptor();
   if (!Init)
     GD->InitState = GlobalInitState::NoInitializer;

diff  --git a/clang/test/AST/ByteCode/literals.cpp 
b/clang/test/AST/ByteCode/literals.cpp
index f4dcd9fbc97b2..5bc3f7f4c815c 100644
--- a/clang/test/AST/ByteCode/literals.cpp
+++ b/clang/test/AST/ByteCode/literals.cpp
@@ -1428,3 +1428,10 @@ namespace OnePastEndCmp {
   constexpr const int *q = &s.a + 1;
   static_assert(p != q, "");
 }
+
+namespace ExternRedecl {
+  extern const int a;
+  constexpr const int *p = &a;
+  constexpr int a = 10;
+  static_assert(*p == 10, "");
+}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to