[clang] [clang][bytecode] Don't call ctor of primitive array elements (PR #151725)

via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 1 09:36:35 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

<details>
<summary>Changes</summary>

We don't do that for single primitive variables, so avoid it for primitive array elements as well.

---
Full diff: https://github.com/llvm/llvm-project/pull/151725.diff


1 Files Affected:

- (modified) clang/lib/AST/ByteCode/Descriptor.cpp (+36-10) 


``````````diff
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));
+    }
   }
 }
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/151725


More information about the cfe-commits mailing list