Skip to content

Commit af63ce3

Browse files
committed
[clang][bytecode] Move bases and virtual bases in moveRecord
The fixme comment turned out to be true.
1 parent 153dd19 commit af63ce3

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
@@ -1699,3 +1699,22 @@ namespace IgnoredMemberExpr {
16991699
};
17001700
static_assert(B{}.foo() == 0, "");
17011701
}
1702+
1703+
#if __cplusplus >= 202002L
1704+
namespace DeadUpcast {
1705+
struct A {};
1706+
struct B : A{};
1707+
constexpr bool foo() {
1708+
1709+
B *pb;
1710+
{
1711+
B b;
1712+
pb = &b;
1713+
}
1714+
A *pa = pb;
1715+
1716+
return true;
1717+
}
1718+
static_assert(foo(), "");
1719+
}
1720+
#endif

0 commit comments

Comments
 (0)