Skip to content

Commit 31abb20

Browse files
authored
[clang][bytecode] Move bases and virtual bases in moveRecord (#127627)
The fixme comment turned out to be true.
1 parent 4cc7d60 commit 31abb20

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

clang/lib/AST/ByteCode/Descriptor.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,7 @@ static void moveRecord(Block *B, std::byte *Src, std::byte *Dst,
237237
assert(D);
238238
assert(D->ElemRecord);
239239

240-
// FIXME: There might be cases where we need to move over the (v)bases as
241-
// well.
240+
// FIXME: Code duplication.
242241
for (const auto &F : D->ElemRecord->fields()) {
243242
auto FieldOffset = F.Offset;
244243
const auto *SrcDesc =
@@ -250,6 +249,26 @@ static void moveRecord(Block *B, std::byte *Src, std::byte *Dst,
250249
if (auto Fn = F.Desc->MoveFn)
251250
Fn(B, Src + FieldOffset, Dst + FieldOffset, F.Desc);
252251
}
252+
253+
for (const auto &Base : D->ElemRecord->bases()) {
254+
auto BaseOffset = Base.Offset;
255+
const auto *SrcDesc =
256+
reinterpret_cast<const InlineDescriptor *>(Src + BaseOffset) - 1;
257+
auto *DestDesc = reinterpret_cast<InlineDescriptor *>(Dst + BaseOffset) - 1;
258+
std::memcpy(DestDesc, SrcDesc, sizeof(InlineDescriptor));
259+
260+
if (auto Fn = Base.Desc->MoveFn)
261+
Fn(B, Src + BaseOffset, Dst + BaseOffset, Base.Desc);
262+
}
263+
264+
for (const auto &VBase : D->ElemRecord->virtual_bases()) {
265+
auto VBaseOffset = VBase.Offset;
266+
const auto *SrcDesc =
267+
reinterpret_cast<const InlineDescriptor *>(Src + VBaseOffset) - 1;
268+
auto *DestDesc =
269+
reinterpret_cast<InlineDescriptor *>(Dst + VBaseOffset) - 1;
270+
std::memcpy(DestDesc, SrcDesc, sizeof(InlineDescriptor));
271+
}
253272
}
254273

255274
static BlockCtorFn getCtorPrim(PrimType Type) {

clang/test/AST/ByteCode/records.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,3 +1715,22 @@ namespace IgnoredMemberExpr {
17151715
};
17161716
static_assert(B{}.foo() == 0, "");
17171717
}
1718+
1719+
#if __cplusplus >= 202002L
1720+
namespace DeadUpcast {
1721+
struct A {};
1722+
struct B : A{};
1723+
constexpr bool foo() {
1724+
1725+
B *pb;
1726+
{
1727+
B b;
1728+
pb = &b;
1729+
}
1730+
A *pa = pb;
1731+
1732+
return true;
1733+
}
1734+
static_assert(foo(), "");
1735+
}
1736+
#endif

0 commit comments

Comments
 (0)