Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 48 additions & 42 deletions clang/lib/AST/ByteCode/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5385,55 +5385,57 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
// instance pointer of the current function frame, but e.g. to the declaration
// currently being initialized. Here we emit the necessary instruction(s) for
// this scenario.
if (!InitStackActive)
if (!InitStackActive || InitStack.empty())
return this->emitThis(E);

if (!InitStack.empty()) {
// If our init stack is, for example:
// 0 Stack: 3 (decl)
// 1 Stack: 6 (init list)
// 2 Stack: 1 (field)
// 3 Stack: 6 (init list)
// 4 Stack: 1 (field)
//
// We want to find the LAST element in it that's an init list,
// which is marked with the K_InitList marker. The index right
// before that points to an init list. We need to find the
// elements before the K_InitList element that point to a base
// (e.g. a decl or This), optionally followed by field, elem, etc.
// In the example above, we want to emit elements [0..2].
unsigned StartIndex = 0;
unsigned EndIndex = 0;
// Find the init list.
for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
if (InitStack[StartIndex].Kind == InitLink::K_InitList ||
InitStack[StartIndex].Kind == InitLink::K_This) {
EndIndex = StartIndex;
--StartIndex;
break;
}
// If our init stack is, for example:
// 0 Stack: 3 (decl)
// 1 Stack: 6 (init list)
// 2 Stack: 1 (field)
// 3 Stack: 6 (init list)
// 4 Stack: 1 (field)
//
// We want to find the LAST element in it that's an init list,
// which is marked with the K_InitList marker. The index right
// before that points to an init list. We need to find the
// elements before the K_InitList element that point to a base
// (e.g. a decl or This), optionally followed by field, elem, etc.
// In the example above, we want to emit elements [0..2].
unsigned StartIndex = 0;
unsigned EndIndex = 0;
// Find the init list.
for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) {
if (InitStack[StartIndex].Kind == InitLink::K_InitList ||
InitStack[StartIndex].Kind == InitLink::K_This) {
EndIndex = StartIndex;
--StartIndex;
break;
}
}

// Walk backwards to find the base.
for (; StartIndex > 0; --StartIndex) {
if (InitStack[StartIndex].Kind == InitLink::K_InitList)
continue;
// Walk backwards to find the base.
for (; StartIndex > 0; --StartIndex) {
if (InitStack[StartIndex].Kind == InitLink::K_InitList)
continue;

if (InitStack[StartIndex].Kind != InitLink::K_Field &&
InitStack[StartIndex].Kind != InitLink::K_Elem)
break;
}
if (InitStack[StartIndex].Kind != InitLink::K_Field &&
InitStack[StartIndex].Kind != InitLink::K_Elem)
break;
}

// Emit the instructions.
for (unsigned I = StartIndex; I != EndIndex; ++I) {
if (InitStack[I].Kind == InitLink::K_InitList)
continue;
if (!InitStack[I].template emit<Emitter>(this, E))
return false;
}
return true;
if (StartIndex == 0 && EndIndex == 0)
EndIndex = InitStack.size() - 1;

assert(StartIndex < EndIndex);

// Emit the instructions.
for (unsigned I = StartIndex; I != (EndIndex + 1); ++I) {
if (InitStack[I].Kind == InitLink::K_InitList)
continue;
if (!InitStack[I].template emit<Emitter>(this, E))
return false;
}
return this->emitThis(E);
return true;
}

template <class Emitter> bool Compiler<Emitter>::visitStmt(const Stmt *S) {
Expand Down Expand Up @@ -6295,6 +6297,10 @@ bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) {
}
assert(NestedField);

unsigned FirstLinkOffset =
R->getField(cast<FieldDecl>(IFD->chain()[0]))->Offset;
InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(InitExpr));
InitLinkScope<Emitter> ILS(this, InitLink::Field(FirstLinkOffset));
if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr,
IsUnion))
return false;
Expand Down
13 changes: 13 additions & 0 deletions clang/test/AST/ByteCode/records.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,19 @@ namespace IndirectFieldInit {
static_assert(s2.x == 1 && s2.y == 2 && s2.a == 3 && s2.b == 4);

#endif


struct B {
struct {
union {
int x = 3;
};
int y = this->x;
};

constexpr B() {}
};
static_assert(B().y == 3, "");
}

namespace InheritedConstructor {
Expand Down