https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/154273
>From 68b2c53e44dbe20cf78e5bff2961464560e5aa9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Tue, 19 Aug 2025 08:22:02 +0200 Subject: [PATCH] [clang][bytecode] Move pointers from extern globals to new decls --- clang/lib/AST/ByteCode/InterpBlock.h | 1 + clang/lib/AST/ByteCode/Pointer.h | 1 + clang/lib/AST/ByteCode/Program.cpp | 35 +++++++++++++++++++--------- clang/test/AST/ByteCode/literals.cpp | 7 ++++++ 4 files changed, 33 insertions(+), 11 deletions(-) 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..6d284b705ee9b 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) { + Block *RedeclBlock = Globals[PIdx]->block(); + if (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 ddf1d2bebdbd0..84bdd649e2257 100644 --- a/clang/test/AST/ByteCode/literals.cpp +++ b/clang/test/AST/ByteCode/literals.cpp @@ -1430,3 +1430,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