From: Timm Bäder Date: Sun, 12 Mar 2023 06:43:53 +0000 (+0100) Subject: [clang][Interp] Fix initializing fields after base class members X-Git-Tag: upstream/17.0.6~12861 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=056042d21b72a86653f88719c0b54b07e35d2144;p=platform%2Fupstream%2Fllvm.git [clang][Interp] Fix initializing fields after base class members Differential Revision: https://reviews.llvm.org/D145860 --- diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index e5c9b26..ee5dd73 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1384,6 +1384,7 @@ bool ByteCodeExprGen::visitRecordInitializer(const Expr *Initializer) { if (!this->emitPopPtr(Initializer)) return false; + ++InitIndex; } else { // Initializer for a direct base class. if (const Record::Base *B = R->getBase(Init->getType())) { @@ -1395,6 +1396,8 @@ bool ByteCodeExprGen::visitRecordInitializer(const Expr *Initializer) { 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 @@ -1407,9 +1410,9 @@ bool ByteCodeExprGen::visitRecordInitializer(const Expr *Initializer) { if (!this->emitPopPtr(Initializer)) return false; + ++InitIndex; } } - ++InitIndex; } return true; diff --git a/clang/test/AST/Interp/cxx20.cpp b/clang/test/AST/Interp/cxx20.cpp index 6cb106a..37be7a4 100644 --- a/clang/test/AST/Interp/cxx20.cpp +++ b/clang/test/AST/Interp/cxx20.cpp @@ -583,3 +583,20 @@ namespace Destructors { 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}; + static_assert(c.a == 1 && c.b == 2 && c.c == 3); +}