Skip to content

Commit 8e3188a

Browse files
authored
[clang][bytecode] Mark CXXDefaultInitExprs in InitLink chain (#166395)
So we know before _what_ entry in the chain we need to look for the InitList. Fixes #166171
1 parent eaf3a91 commit 8e3188a

File tree

3 files changed

+40
-9
lines changed

3 files changed

+40
-9
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5432,8 +5432,7 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
54325432
unsigned EndIndex = 0;
54335433
// Find the init list.
54345434
for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
5435-
if (InitStack[StartIndex].Kind == InitLink::K_InitList ||
5436-
InitStack[StartIndex].Kind == InitLink::K_This) {
5435+
if (InitStack[StartIndex].Kind == InitLink::K_DIE) {
54375436
EndIndex = StartIndex;
54385437
--StartIndex;
54395438
break;
@@ -5446,7 +5445,8 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
54465445
continue;
54475446

54485447
if (InitStack[StartIndex].Kind != InitLink::K_Field &&
5449-
InitStack[StartIndex].Kind != InitLink::K_Elem)
5448+
InitStack[StartIndex].Kind != InitLink::K_Elem &&
5449+
InitStack[StartIndex].Kind != InitLink::K_DIE)
54505450
break;
54515451
}
54525452

@@ -5457,7 +5457,8 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
54575457

54585458
// Emit the instructions.
54595459
for (unsigned I = StartIndex; I != (EndIndex + 1); ++I) {
5460-
if (InitStack[I].Kind == InitLink::K_InitList)
5460+
if (InitStack[I].Kind == InitLink::K_InitList ||
5461+
InitStack[I].Kind == InitLink::K_DIE)
54615462
continue;
54625463
if (!InitStack[I].template emit<Emitter>(this, E))
54635464
return false;
@@ -6328,8 +6329,8 @@ bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) {
63286329

63296330
unsigned FirstLinkOffset =
63306331
R->getField(cast<FieldDecl>(IFD->chain()[0]))->Offset;
6331-
InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(InitExpr));
63326332
InitLinkScope<Emitter> ILS(this, InitLink::Field(FirstLinkOffset));
6333+
InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(InitExpr));
63336334
if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr,
63346335
IsUnion))
63356336
return false;

clang/lib/AST/ByteCode/Compiler.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,14 @@ struct InitLink {
5252
K_Decl = 3,
5353
K_Elem = 5,
5454
K_RVO = 6,
55-
K_InitList = 7
55+
K_InitList = 7,
56+
K_DIE = 8,
5657
};
5758

5859
static InitLink This() { return InitLink{K_This}; }
5960
static InitLink InitList() { return InitLink{K_InitList}; }
6061
static InitLink RVO() { return InitLink{K_RVO}; }
62+
static InitLink DIE() { return InitLink{K_DIE}; }
6163
static InitLink Field(unsigned Offset) {
6264
InitLink IL{K_Field};
6365
IL.Offset = Offset;
@@ -668,22 +670,29 @@ template <class Emitter> class InitLinkScope final {
668670

669671
~InitLinkScope() { this->Ctx->InitStack.pop_back(); }
670672

671-
private:
673+
public:
672674
Compiler<Emitter> *Ctx;
673675
};
674676

675677
template <class Emitter> class InitStackScope final {
676678
public:
677679
InitStackScope(Compiler<Emitter> *Ctx, bool Active)
678-
: Ctx(Ctx), OldValue(Ctx->InitStackActive) {
680+
: Ctx(Ctx), OldValue(Ctx->InitStackActive), Active(Active) {
679681
Ctx->InitStackActive = Active;
682+
if (Active)
683+
Ctx->InitStack.push_back(InitLink::DIE());
680684
}
681685

682-
~InitStackScope() { this->Ctx->InitStackActive = OldValue; }
686+
~InitStackScope() {
687+
this->Ctx->InitStackActive = OldValue;
688+
if (Active)
689+
Ctx->InitStack.pop_back();
690+
}
683691

684692
private:
685693
Compiler<Emitter> *Ctx;
686694
bool OldValue;
695+
bool Active;
687696
};
688697

689698
} // namespace interp

clang/test/AST/ByteCode/cxx14.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,24 @@ constexpr int(*null_ptr)() = nullptr;
77
constexpr int test4 = (*null_ptr)(); // both-error {{must be initialized by a constant expression}} \
88
// both-note {{evaluates to a null function pointer}}
99

10+
struct E {
11+
int n = 0;
12+
struct {
13+
void *x = this;
14+
};
15+
void *y = this;
16+
};
17+
constexpr E e1 = E();
18+
static_assert(e1.x != e1.y, "");
19+
constexpr E e2 = E{0};
20+
static_assert(e2.x != e2.y, "");
21+
22+
struct S {
23+
int &&a = 2;
24+
int b[1]{a};
25+
};
26+
constexpr int foo() {
27+
S s{12};
28+
return s.b[0];
29+
}
30+
static_assert(foo() == 12, "");

0 commit comments

Comments
 (0)