Author: Timm Baeder Date: 2025-08-02T14:55:07+02:00 New Revision: 834621564fffb792008a6177ecade1c685519820
URL: https://github.com/llvm/llvm-project/commit/834621564fffb792008a6177ecade1c685519820 DIFF: https://github.com/llvm/llvm-project/commit/834621564fffb792008a6177ecade1c685519820.diff LOG: [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. Added: Modified: clang/lib/AST/ByteCode/Descriptor.cpp Removed: ################################################################################ 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 <typename T> static constexpr bool needsCtor() { + if constexpr (std::is_same_v<T, Integral<8, true>> || + std::is_same_v<T, Integral<8, false>> || + std::is_same_v<T, Integral<16, true>> || + std::is_same_v<T, Integral<16, false>> || + std::is_same_v<T, Integral<32, true>> || + std::is_same_v<T, Integral<32, false>> || + std::is_same_v<T, Integral<64, true>> || + std::is_same_v<T, Integral<64, false>> || + std::is_same_v<T, Boolean>) + return false; + + return true; +} + template <typename T> static void ctorTy(Block *, std::byte *Ptr, bool, bool, bool, bool, bool, const Descriptor *) { + static_assert(needsCtor<T>()); new (Ptr) T(); } template <typename T> static void dtorTy(Block *, std::byte *Ptr, const Descriptor *) { + static_assert(needsCtor<T>()); reinterpret_cast<T *>(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<T *>(Ptr)[I]) T(); + if constexpr (needsCtor<T>()) { + Ptr += sizeof(InitMapPtr); + for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) { + new (&reinterpret_cast<T *>(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<T *>(Ptr)[I].~T(); + + if constexpr (needsCtor<T>()) { + Ptr += sizeof(InitMapPtr); + for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) { + reinterpret_cast<T *>(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<T *>(Src)[I]; - auto *DstPtr = &reinterpret_cast<T *>(Dst)[I]; - new (DstPtr) T(std::move(*SrcPtr)); + if constexpr (!needsCtor<T>()) { + std::memcpy(Dst, Src, D->getNumElems() * D->getElemSize()); + } else { + for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) { + auto *SrcPtr = &reinterpret_cast<T *>(Src)[I]; + auto *DstPtr = &reinterpret_cast<T *>(Dst)[I]; + new (DstPtr) T(std::move(*SrcPtr)); + } } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits