Skip to content

Commit 8346215

Browse files
authored
[clang][bytecode] Don't call ctor of primitive array elements (#151725)
We don't do that for single primitive variables, so avoid it for primitive array elements as well.
1 parent 41803a2 commit 8346215

File tree

1 file changed

+36
-10
lines changed

1 file changed

+36
-10
lines changed

clang/lib/AST/ByteCode/Descriptor.cpp

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,31 @@
2121
using namespace clang;
2222
using namespace clang::interp;
2323

24+
template <typename T> static constexpr bool needsCtor() {
25+
if constexpr (std::is_same_v<T, Integral<8, true>> ||
26+
std::is_same_v<T, Integral<8, false>> ||
27+
std::is_same_v<T, Integral<16, true>> ||
28+
std::is_same_v<T, Integral<16, false>> ||
29+
std::is_same_v<T, Integral<32, true>> ||
30+
std::is_same_v<T, Integral<32, false>> ||
31+
std::is_same_v<T, Integral<64, true>> ||
32+
std::is_same_v<T, Integral<64, false>> ||
33+
std::is_same_v<T, Boolean>)
34+
return false;
35+
36+
return true;
37+
}
38+
2439
template <typename T>
2540
static void ctorTy(Block *, std::byte *Ptr, bool, bool, bool, bool, bool,
2641
const Descriptor *) {
42+
static_assert(needsCtor<T>());
2743
new (Ptr) T();
2844
}
2945

3046
template <typename T>
3147
static void dtorTy(Block *, std::byte *Ptr, const Descriptor *) {
48+
static_assert(needsCtor<T>());
3249
reinterpret_cast<T *>(Ptr)->~T();
3350
}
3451

@@ -45,9 +62,11 @@ static void ctorArrayTy(Block *, std::byte *Ptr, bool, bool, bool, bool, bool,
4562
const Descriptor *D) {
4663
new (Ptr) InitMapPtr(std::nullopt);
4764

48-
Ptr += sizeof(InitMapPtr);
49-
for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) {
50-
new (&reinterpret_cast<T *>(Ptr)[I]) T();
65+
if constexpr (needsCtor<T>()) {
66+
Ptr += sizeof(InitMapPtr);
67+
for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) {
68+
new (&reinterpret_cast<T *>(Ptr)[I]) T();
69+
}
5170
}
5271
}
5372

@@ -57,9 +76,12 @@ static void dtorArrayTy(Block *, std::byte *Ptr, const Descriptor *D) {
5776

5877
if (IMP)
5978
IMP = std::nullopt;
60-
Ptr += sizeof(InitMapPtr);
61-
for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) {
62-
reinterpret_cast<T *>(Ptr)[I].~T();
79+
80+
if constexpr (needsCtor<T>()) {
81+
Ptr += sizeof(InitMapPtr);
82+
for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) {
83+
reinterpret_cast<T *>(Ptr)[I].~T();
84+
}
6385
}
6486
}
6587

@@ -74,10 +96,14 @@ static void moveArrayTy(Block *, std::byte *Src, std::byte *Dst,
7496
}
7597
Src += sizeof(InitMapPtr);
7698
Dst += sizeof(InitMapPtr);
77-
for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) {
78-
auto *SrcPtr = &reinterpret_cast<T *>(Src)[I];
79-
auto *DstPtr = &reinterpret_cast<T *>(Dst)[I];
80-
new (DstPtr) T(std::move(*SrcPtr));
99+
if constexpr (!needsCtor<T>()) {
100+
std::memcpy(Dst, Src, D->getNumElems() * D->getElemSize());
101+
} else {
102+
for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) {
103+
auto *SrcPtr = &reinterpret_cast<T *>(Src)[I];
104+
auto *DstPtr = &reinterpret_cast<T *>(Dst)[I];
105+
new (DstPtr) T(std::move(*SrcPtr));
106+
}
81107
}
82108
}
83109

0 commit comments

Comments
 (0)