Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1410,6 +1410,7 @@ if (!this->emitPopPtr(Initializer)) return false; + ++InitIndex; } else { // Initializer for a direct base class. if (const Record::Base *B = R->getBase(Init->getType())) { @@ -1421,6 +1422,8 @@ if (!this->emitPopPtr(Initializer)) return false; + // Base initializers don't increase InitIndex, since they don't count + // into the Record's fields. } else { const Record::Field *FieldToInit = R->getField(InitIndex); // Non-primitive case. Get a pointer to the field-to-initialize @@ -1433,9 +1436,9 @@ if (!this->emitPopPtr(Initializer)) return false; + ++InitIndex; } } - ++InitIndex; } return true; Index: clang/test/AST/Interp/cxx20.cpp =================================================================== --- clang/test/AST/Interp/cxx20.cpp +++ clang/test/AST/Interp/cxx20.cpp @@ -583,3 +583,19 @@ constexpr Outer O; static_assert(O.bar() == 12); } + +namespace BaseAndFieldInit { + struct A { + int a; + }; + + struct B : A { + int b; + }; + + struct C : B { + int c; + }; + + constexpr C c = {1,2,3}; +}