[clang] [clang][bytecode] Fix initializing bases via DefaultInitExpr (PR #215499)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 11 02:14:45 PDT 2026
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/215499
>From ce6fb494322f3a05da6d45a4807cf7e9f5578cfa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Tue, 11 Aug 2026 10:49:53 +0200
Subject: [PATCH] [clang][bytecode] Fix initializing bases via DefaultInitExpr
---
clang/lib/AST/ByteCode/Compiler.cpp | 10 ++++++++++
clang/lib/AST/ByteCode/Compiler.h | 18 ++++++++++++------
clang/test/AST/ByteCode/records.cpp | 10 ++++++++++
3 files changed, 32 insertions(+), 6 deletions(-)
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, "");
+}
More information about the cfe-commits
mailing list