Skip to content

Commit fedd3b0

Browse files
authored
[clang][bytecode] Remove dummy variables once they are proper globals (#166174)
Dummy variables have an entry in `Program::Globals`, but they are not added to `GlobalIndices`. When registering redeclarations, we used to only patch up the global indices, but that left the dummy variables alone. Update the dummy variables of all redeclarations as well. Fixes #165952
1 parent d249e67 commit fedd3b0

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

clang/lib/AST/ByteCode/Program.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,21 +218,42 @@ UnsignedOrNone Program::createGlobal(const ValueDecl *VD, const Expr *Init) {
218218
return std::nullopt;
219219

220220
Global *NewGlobal = Globals[*Idx];
221+
// Note that this loop has one iteration where Redecl == VD.
221222
for (const Decl *Redecl : VD->redecls()) {
222-
unsigned &PIdx = GlobalIndices[Redecl];
223+
224+
// If this redecl was registered as a dummy variable, it is now a proper
225+
// global variable and points to the block we just created.
226+
if (auto DummyIt = DummyVariables.find(Redecl);
227+
DummyIt != DummyVariables.end()) {
228+
assert(!Globals[DummyIt->second]->block()->hasPointers());
229+
Globals[DummyIt->second] = NewGlobal;
230+
DummyVariables.erase(DummyIt);
231+
}
232+
// If the redeclaration hasn't been registered yet at all, we just set its
233+
// global index to Idx. If it has been registered yet, it might have
234+
// pointers pointing to it and we need to transfer those pointers to the new
235+
// block.
236+
auto [Iter, Inserted] = GlobalIndices.try_emplace(Redecl);
237+
if (Inserted) {
238+
GlobalIndices[Redecl] = *Idx;
239+
continue;
240+
}
241+
223242
if (Redecl != VD) {
224-
if (Block *RedeclBlock = Globals[PIdx]->block();
243+
if (Block *RedeclBlock = Globals[Iter->second]->block();
225244
RedeclBlock->isExtern()) {
226-
Globals[PIdx] = NewGlobal;
245+
227246
// All pointers pointing to the previous extern decl now point to the
228247
// new decl.
229248
// A previous iteration might've already fixed up the pointers for this
230249
// global.
231250
if (RedeclBlock != NewGlobal->block())
232251
RedeclBlock->movePointersTo(NewGlobal->block());
252+
253+
Globals[Iter->second] = NewGlobal;
233254
}
234255
}
235-
PIdx = *Idx;
256+
Iter->second = *Idx;
236257
}
237258

238259
return *Idx;

clang/lib/AST/ByteCode/Program.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@ class Program final {
205205
const Block *block() const { return &B; }
206206

207207
private:
208-
/// Required metadata - does not actually track pointers.
209208
Block B;
210209
};
211210

clang/test/AST/ByteCode/records.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,3 +1882,14 @@ namespace MethodWillHaveBody {
18821882
}
18831883
int n = f(0); // both-note {{instantiation of}}
18841884
}
1885+
1886+
namespace StaticRedecl {
1887+
struct T {
1888+
static T tt;
1889+
constexpr T() : p(&tt) {}
1890+
T *p;
1891+
};
1892+
T T::tt;
1893+
constexpr T t;
1894+
static_assert(t.p == &T::tt, "");
1895+
}

0 commit comments

Comments
 (0)