diff --git a/clang/lib/AST/Interp/Compiler.cpp b/clang/lib/AST/Interp/Compiler.cpp index 24140b23c1f0bb..7da711ed485db1 100644 --- a/clang/lib/AST/Interp/Compiler.cpp +++ b/clang/lib/AST/Interp/Compiler.cpp @@ -1334,6 +1334,7 @@ bool Compiler::visitInitList(ArrayRef Inits, auto initPrimitiveField = [=](const Record::Field *FieldToInit, const Expr *Init, PrimType T) -> bool { + InitStackScope ISS(this, isa(Init)); if (!this->visit(Init)) return false; @@ -1344,6 +1345,7 @@ bool Compiler::visitInitList(ArrayRef Inits, auto initCompositeField = [=](const Record::Field *FieldToInit, const Expr *Init) -> bool { + InitStackScope ISS(this, isa(Init)); InitLinkScope ILS(this, InitLink::Field(FieldToInit->Offset)); // Non-primitive case. Get a pointer to the field-to-initialize // on the stack and recurse into visitInitializer(). @@ -4088,12 +4090,7 @@ template bool Compiler::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) { SourceLocScope SLS(this, E); - bool Old = InitStackActive; - InitStackActive = - !(E->getUsedContext()->getDeclKind() == Decl::CXXConstructor); - bool Result = this->delegate(E->getExpr()); - InitStackActive = Old; - return Result; + return this->delegate(E->getExpr()); } template @@ -4151,6 +4148,9 @@ bool Compiler::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 || !E->isImplicit()) + return this->emitThis(E); + if (InitStackActive && !InitStack.empty()) { unsigned StartIndex = 0; for (StartIndex = InitStack.size() - 1; StartIndex > 0; --StartIndex) { diff --git a/clang/lib/AST/Interp/Compiler.h b/clang/lib/AST/Interp/Compiler.h index 6df723df2b4447..084f5aef25f8e6 100644 --- a/clang/lib/AST/Interp/Compiler.h +++ b/clang/lib/AST/Interp/Compiler.h @@ -33,6 +33,7 @@ template class DestructorScope; template class VariableScope; template class DeclScope; template class InitLinkScope; +template class InitStackScope; template class OptionScope; template class ArrayIndexScope; template class SourceLocScope; @@ -298,6 +299,7 @@ class Compiler : public ConstStmtVisitor, bool>, friend class DestructorScope; friend class DeclScope; friend class InitLinkScope; + friend class InitStackScope; friend class OptionScope; friend class ArrayIndexScope; friend class SourceLocScope; @@ -612,6 +614,20 @@ template class InitLinkScope final { Compiler *Ctx; }; +template class InitStackScope final { +public: + InitStackScope(Compiler *Ctx, bool Active) + : Ctx(Ctx), OldValue(Ctx->InitStackActive) { + Ctx->InitStackActive = Active; + } + + ~InitStackScope() { this->Ctx->InitStackActive = OldValue; } + +private: + Compiler *Ctx; + bool OldValue; +}; + } // namespace interp } // namespace clang