Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -611,9 +611,11 @@ return false; } else if (Optional T = classify(InitType)) { // Visit the primitive element like normal. + if (!this->emitDupPtr(Init)) + return false; if (!this->visit(Init)) return false; - if (!this->emitInitElem(*T, ElementIndex, Init)) + if (!this->emitInitElemPop(*T, ElementIndex, Init)) return false; } else { assert(false && "Unhandled type in array initializer initlist"); @@ -621,12 +623,13 @@ ++ElementIndex; } - - } else { - assert(false && "Unknown expression for array initialization"); + return true; + } else if (const auto *DIE = dyn_cast(Initializer)) { + return this->visitInitializer(DIE->getExpr()); } - return true; + assert(false && "Unknown expression for array initialization"); + return false; } template @@ -678,7 +681,10 @@ return this->visit(CE); } + } else if (const auto *DIE = dyn_cast(Initializer)) { + return this->visitInitializer(DIE->getExpr()); } + return false; } Index: clang/lib/AST/Interp/ByteCodeStmtGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeStmtGen.cpp +++ clang/lib/AST/Interp/ByteCodeStmtGen.cpp @@ -102,10 +102,9 @@ 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())) { - const Record::Field *F = R->getField(Member); - if (!this->emitDupPtr(InitExpr)) return false; @@ -115,7 +114,19 @@ if (!this->emitInitField(*T, F->Offset, InitExpr)) return false; } else { - assert(false && "Handle initializer for non-primitive values"); + // Non-primitive case. Get a pointer to the field-to-initialize + // on the stack and call visitInitialzer() for it. + if (!this->emitDupPtr(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 @@ -13,7 +13,8 @@ int a = 20; int b = 30; bool c = true; - // BoolPair bp = {true, false}; FIXME + BoolPair bp = {true, false}; + int numbers[3] = {1,2,3}; static const int five = 5; static constexpr int getFive() { @@ -37,6 +38,13 @@ static_assert(ints.c, ""); static_assert(ints.getTen() == 10, ""); +constexpr const BoolPair &BP = ints.bp; +static_assert(BP.first, ""); +static_assert(!BP.second, ""); +static_assert(ints.bp.first, ""); +static_assert(!ints.bp.second, ""); + + constexpr Ints ints2{-20, -30, false}; static_assert(ints2.a == -20, ""); static_assert(ints2.b == -30, "");