[clang] [clang][bytecode] Move pointers from extern globals to new decls (PR #154273)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 18 23:25:30 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/154273.diff
4 Files Affected:
- (modified) clang/lib/AST/ByteCode/InterpBlock.h (+1)
- (modified) clang/lib/AST/ByteCode/Pointer.h (+1)
- (modified) clang/lib/AST/ByteCode/Program.cpp (+21-11)
- (modified) clang/test/AST/ByteCode/literals.cpp (+7)
``````````diff
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..af65272819351 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -213,19 +213,29 @@ 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)
+ Ptr->PointeeStorage.BS.Pointee = NewGlobal->block();
}
- PIdx = *Idx;
}
- return *Idx;
+ PIdx = *Idx;
}
- return std::nullopt;
+
+ return *Idx;
}
std::optional<unsigned> Program::createGlobal(const Expr *E) {
@@ -264,7 +274,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..54544464c28ea 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);
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/154273
More information about the cfe-commits
mailing list