Author: Timm Baeder Date: 2026-08-11T14:13:08+02:00 New Revision: 87644e275d38ea397360ffb9c9b9faf9323d15b2
URL: https://github.com/llvm/llvm-project/commit/87644e275d38ea397360ffb9c9b9faf9323d15b2 DIFF: https://github.com/llvm/llvm-project/commit/87644e275d38ea397360ffb9c9b9faf9323d15b2.diff LOG: [clang][bytecode] Fix initializing bases via DefaultInitExpr (#215499) We can't just ignore the base initializer here, we need to get the base pointer and everything else should work just fine. Added: Modified: clang/lib/AST/ByteCode/Compiler.cpp clang/lib/AST/ByteCode/Compiler.h clang/test/AST/ByteCode/records.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 316b2a4f092f9..9b2c9191f729a 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -340,6 +340,8 @@ bool InitLink::emit(Compiler<Emitter> *Ctx, const Expr *E) const { case K_Field: // We're assuming there's a base pointer on the stack already. return Ctx->emitGetPtrFieldPop(Offset, E); + case K_Base: + return Ctx->emitGetPtrBasePop(Offset, false, E); case K_Temp: return Ctx->emitGetPtrLocal(Offset, E); case K_Decl: @@ -2398,6 +2400,8 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits, for (unsigned BI = 0; BI != R->getNumBases(); ++BI) { const Expr *Init = Inits[BI]; const Record::Base *B = R->getBase(BI); + InitStackScope<Emitter> ISS(this, isa<CXXDefaultInitExpr>(Init)); + InitLinkScope<Emitter> ILS(this, InitLink::Base(B->Offset)); if (!this->emitGetPtrBase(B->Offset, Init)) return false; if (!this->visitInitializerPop(Init)) @@ -6468,6 +6472,7 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) { if (InitStack[StartIndex].Kind != InitLink::K_Field && InitStack[StartIndex].Kind != InitLink::K_Elem && + InitStack[StartIndex].Kind != InitLink::K_Base && InitStack[StartIndex].Kind != InitLink::K_DIE) break; } @@ -6475,6 +6480,11 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) { if (StartIndex == 0 && EndIndex == 0) EndIndex = InitStack.size() - 1; + assert(InitStack[StartIndex].Kind == InitLink::K_Decl || + InitStack[StartIndex].Kind == InitLink::K_This || + InitStack[StartIndex].Kind == InitLink::K_Temp || + InitStack[StartIndex].Kind == InitLink::K_RVO); + // NOTE: This could be StartIndex < EndIndex, but we're also abusing the // InitStack mechanism in visitWithSubstitutions to have the This pointer // _just_ be a local variable. diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index 46d6b1a49c001..40589b45fa051 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -49,12 +49,13 @@ struct InitLink { enum { K_This = 0, K_Field = 1, - K_Temp = 2, - K_Decl = 3, - K_Elem = 5, - K_RVO = 6, - K_InitList = 7, - K_DIE = 8, + K_Base = 2, + K_Temp = 3, + K_Decl = 4, + K_Elem = 6, + K_RVO = 7, + K_InitList = 8, + K_DIE = 9, }; static InitLink This() { return InitLink{K_This}; } @@ -66,6 +67,11 @@ struct InitLink { IL.Offset = Offset; return IL; } + static InitLink Base(unsigned Offset) { + InitLink IL{K_Base}; + IL.Offset = Offset; + return IL; + } static InitLink Temp(unsigned Offset) { InitLink IL{K_Temp}; IL.Offset = Offset; diff --git a/clang/test/AST/ByteCode/records.cpp b/clang/test/AST/ByteCode/records.cpp index b792b56563b2f..36b5cb62fe95f 100644 --- a/clang/test/AST/ByteCode/records.cpp +++ b/clang/test/AST/ByteCode/records.cpp @@ -2044,3 +2044,13 @@ namespace VariadicCtorStartsLifetime { /// Used to not start the lifetime of 's'. constexpr C c; } + +namespace BaseInitViaDIE { + struct S { + int a = 42, b = a; + }; + + struct SS : S {}; + constexpr SS ss {}; + static_assert(ss.b == 42, ""); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
