Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -115,6 +115,7 @@ case CK_NoOp: case CK_UserDefinedConversion: case CK_NullToPointer: + case CK_UncheckedDerivedToBase: return this->Visit(SubExpr); case CK_IntegralToBoolean: Index: clang/lib/AST/Interp/ByteCodeStmtGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeStmtGen.cpp +++ clang/lib/AST/Interp/ByteCodeStmtGen.cpp @@ -100,31 +100,40 @@ const Record *R = this->getRecord(RD); for (const auto *Init : Ctor->inits()) { - const FieldDecl *Member = Init->getMember(); const Expr *InitExpr = Init->getInit(); - const Record::Field *F = R->getField(Member); - - if (Optional T = this->classify(InitExpr->getType())) { + if (const FieldDecl *Member = Init->getMember()) { + const Record::Field *F = R->getField(Member); + + if (Optional T = this->classify(InitExpr->getType())) { + if (!this->emitThis(InitExpr)) + return false; + + if (!this->visit(InitExpr)) + return false; + + if (!this->emitInitField(*T, F->Offset, InitExpr)) + return false; + } else { + // Non-primitive case. Get a pointer to the field-to-initialize + // on the stack and call visitInitialzer() for it. + if (!this->emitThis(InitExpr)) + return false; + + if (!this->emitGetPtrField(F->Offset, InitExpr)) + return false; + + if (!this->visitInitializer(InitExpr)) + return false; + + if (!this->emitPopPtr(InitExpr)) + return false; + } + } else if (const Type *Base = Init->getBaseClass()) { + // Base class initializer. if (!this->emitThis(InitExpr)) return false; - - if (!this->visit(InitExpr)) - return false; - - if (!this->emitInitField(*T, F->Offset, InitExpr)) - return false; - } else { - // Non-primitive case. Get a pointer to the field-to-initialize - // on the stack and call visitInitialzer() for it. - if (!this->emitThis(InitExpr)) - return false; - - if (!this->emitGetPtrField(F->Offset, InitExpr)) - return false; - if (!this->visitInitializer(InitExpr)) return false; - if (!this->emitPopPtr(InitExpr)) return false; } Index: clang/test/AST/Interp/records.cpp =================================================================== --- clang/test/AST/Interp/records.cpp +++ clang/test/AST/Interp/records.cpp @@ -157,3 +157,20 @@ static_assert(LT2.v[0].second == false, ""); static_assert(LT2.v[2].first == true, ""); static_assert(LT2.v[2].second == false, ""); + +class Base { +public: + int i; + constexpr Base() : i(10) {} + constexpr Base(int i) : i(i) {} +}; + +class A : public Base { +public: + constexpr A() : Base(100) {} + constexpr A(int a) : Base(a) {} +}; +constexpr A a{}; +static_assert(a.i == 100, ""); +constexpr A a2{12}; +static_assert(a2.i == 12, "");