[clang][bytecode] Move pointers from extern globals to new decls (#154273)
This commit is contained in:
parent
d9d5090b03
commit
fb8ee3adb6
@ -149,6 +149,7 @@ private:
|
||||
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)
|
||||
|
@ -804,6 +804,7 @@ private:
|
||||
friend class InterpState;
|
||||
friend struct InitMap;
|
||||
friend class DynamicAllocator;
|
||||
friend class Program;
|
||||
|
||||
/// Returns the embedded descriptor preceding a field.
|
||||
InlineDescriptor *getInlineDesc() const {
|
||||
|
@ -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;
|
||||
|
@ -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, "");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user