[clang] [clang][bytecode] Fix initializing record bases from init lists (PR #206408)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 29 00:30:47 PDT 2026
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/206408
>From dded5670e8dded95d804a0b719f8a5cb6d615860 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Mon, 29 Jun 2026 08:42:24 +0200
Subject: [PATCH] [clang][bytecode] Fix initializing record bases from init
lists
---
clang/lib/AST/ByteCode/Compiler.cpp | 52 +++++++++++++++--------------
clang/test/AST/ByteCode/cxx17.cpp | 16 +++++++++
2 files changed, 43 insertions(+), 25 deletions(-)
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 20b110b38ff78..c5d0501b4a21e 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -2153,43 +2153,45 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits,
}
assert(!R->isUnion());
- unsigned InitIndex = 0;
- for (const Expr *Init : Inits) {
- // Skip unnamed bitfields.
- while (InitIndex < R->getNumFields() &&
- R->getField(InitIndex)->isUnnamedBitField())
- ++InitIndex;
+ for (unsigned BI = 0; BI != R->getNumBases(); ++BI) {
+ const Expr *Init = Inits[BI];
+ const Record::Base *B = R->getBase(BI);
+ if (!this->emitGetPtrBase(B->Offset, Init))
+ return false;
+ if (!this->visitInitializerPop(Init))
+ return false;
+ }
+
+ unsigned FieldIndex = 0;
+ for (unsigned FI = R->getNumBases(); FI != Inits.size();) {
+ const Record::Field *FieldToInit = R->getField(FieldIndex);
+ if (FieldToInit->isUnnamedBitField()) {
+ ++FieldIndex;
+ continue;
+ }
+ const Expr *Init = Inits[FI];
// If this is a child of a DesignatedInitUpdateExpr, skip elements which
// aren't supposed to be modified.
if (isa<NoInitExpr>(Init)) {
- ++InitIndex;
+ ++FieldIndex;
+ ++FI;
continue;
}
if (OptPrimType T = classify(Init)) {
- const Record::Field *FieldToInit = R->getField(InitIndex);
if (!initPrimitiveField(FieldToInit, Init, *T))
return false;
- ++InitIndex;
- } else {
- // Initializer for a direct base class.
- if (const Record::Base *B = R->getBase(Init->getType())) {
- if (!this->emitGetPtrBase(B->Offset, Init))
- return false;
-
- if (!this->visitInitializerPop(Init))
- 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);
- if (!initCompositeField(FieldToInit, Init))
- return false;
- ++InitIndex;
- }
+ } else if (!initCompositeField(FieldToInit, Init)) {
+ return false;
}
+
+ ++FI;
+ ++FieldIndex;
}
+
+ assert(R->getNumVirtualBases() == 0);
+
return this->emitFinishInit(E);
}
diff --git a/clang/test/AST/ByteCode/cxx17.cpp b/clang/test/AST/ByteCode/cxx17.cpp
index 5d6e925eab32d..9168f0d34d872 100644
--- a/clang/test/AST/ByteCode/cxx17.cpp
+++ b/clang/test/AST/ByteCode/cxx17.cpp
@@ -178,3 +178,19 @@ namespace ZeroInCheckInvoke {
thread_local const auto &[s, t, u] = foo(C{}); // both-warning {{thread_local}}
#endif
}
+
+namespace InitListBaseInit {
+ struct A {
+ int m;
+ constexpr A(int m) : m(m) {}
+ };
+
+ struct B : A {
+ A a;
+ int i;
+ };
+ constexpr B b{42, 43};
+ static_assert(b.m == 42);
+ static_assert(b.a.m == 43);
+ static_assert(b.i == 0);
+}
More information about the cfe-commits
mailing list