Skip to content

Commit 7e589cb

Browse files
committed
[clang][bytecode] Mark CXXDefaultInitExprs in InitLink chain
So we know before _what_ entry in the chain we need to look for the InitList. Fixes #166171
1 parent 912cc5f commit 7e589cb

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
@@ -5412,8 +5412,7 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
54125412
unsigned EndIndex = 0;
54135413
// Find the init list.
54145414
for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
5415-
if (InitStack[StartIndex].Kind == InitLink::K_InitList ||
5416-
InitStack[StartIndex].Kind == InitLink::K_This) {
5415+
if (InitStack[StartIndex].Kind == InitLink::K_DIE) {
54175416
EndIndex = StartIndex;
54185417
--StartIndex;
54195418
break;
@@ -5426,7 +5425,8 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
54265425
continue;
54275426

54285427
if (InitStack[StartIndex].Kind != InitLink::K_Field &&
5429-
InitStack[StartIndex].Kind != InitLink::K_Elem)
5428+
InitStack[StartIndex].Kind != InitLink::K_Elem &&
5429+
InitStack[StartIndex].Kind != InitLink::K_DIE)
54305430
break;
54315431
}
54325432

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

54385438
// Emit the instructions.
54395439
for (unsigned I = StartIndex; I != (EndIndex + 1); ++I) {
5440-
if (InitStack[I].Kind == InitLink::K_InitList)
5440+
if (InitStack[I].Kind == InitLink::K_InitList ||
5441+
InitStack[I].Kind == InitLink::K_DIE)
54415442
continue;
54425443
if (!InitStack[I].template emit<Emitter>(this, E))
54435444
return false;
@@ -6306,8 +6307,8 @@ bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) {
63066307

63076308
unsigned FirstLinkOffset =
63086309
R->getField(cast<FieldDecl>(IFD->chain()[0]))->Offset;
6309-
InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(InitExpr));
63106310
InitLinkScope<Emitter> ILS(this, InitLink::Field(FirstLinkOffset));
6311+
InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(InitExpr));
63116312
if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr,
63126313
IsUnion))
63136314
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)