diff --git a/clang/lib/AST/ByteCode/Descriptor.cpp b/clang/lib/AST/ByteCode/Descriptor.cpp index 5b9f44518fcc2..7403e90ce53db 100644 --- a/clang/lib/AST/ByteCode/Descriptor.cpp +++ b/clang/lib/AST/ByteCode/Descriptor.cpp @@ -21,14 +21,31 @@ using namespace clang; using namespace clang::interp; +template static constexpr bool needsCtor() { + if constexpr (std::is_same_v> || + std::is_same_v> || + std::is_same_v> || + std::is_same_v> || + std::is_same_v> || + std::is_same_v> || + std::is_same_v> || + std::is_same_v> || + std::is_same_v) + return false; + + return true; +} + template static void ctorTy(Block *, std::byte *Ptr, bool, bool, bool, bool, bool, const Descriptor *) { + static_assert(needsCtor()); new (Ptr) T(); } template static void dtorTy(Block *, std::byte *Ptr, const Descriptor *) { + static_assert(needsCtor()); reinterpret_cast(Ptr)->~T(); } @@ -45,9 +62,11 @@ static void ctorArrayTy(Block *, std::byte *Ptr, bool, bool, bool, bool, bool, const Descriptor *D) { new (Ptr) InitMapPtr(std::nullopt); - Ptr += sizeof(InitMapPtr); - for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) { - new (&reinterpret_cast(Ptr)[I]) T(); + if constexpr (needsCtor()) { + Ptr += sizeof(InitMapPtr); + for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) { + new (&reinterpret_cast(Ptr)[I]) T(); + } } } @@ -57,9 +76,12 @@ static void dtorArrayTy(Block *, std::byte *Ptr, const Descriptor *D) { if (IMP) IMP = std::nullopt; - Ptr += sizeof(InitMapPtr); - for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) { - reinterpret_cast(Ptr)[I].~T(); + + if constexpr (needsCtor()) { + Ptr += sizeof(InitMapPtr); + for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) { + reinterpret_cast(Ptr)[I].~T(); + } } } @@ -74,10 +96,14 @@ static void moveArrayTy(Block *, std::byte *Src, std::byte *Dst, } Src += sizeof(InitMapPtr); Dst += sizeof(InitMapPtr); - for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) { - auto *SrcPtr = &reinterpret_cast(Src)[I]; - auto *DstPtr = &reinterpret_cast(Dst)[I]; - new (DstPtr) T(std::move(*SrcPtr)); + if constexpr (!needsCtor()) { + std::memcpy(Dst, Src, D->getNumElems() * D->getElemSize()); + } else { + for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) { + auto *SrcPtr = &reinterpret_cast(Src)[I]; + auto *DstPtr = &reinterpret_cast(Dst)[I]; + new (DstPtr) T(std::move(*SrcPtr)); + } } }