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

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


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

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

>From 7618f122c34949742f0c19a61705c1f2045f4a31 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Fri, 1 Aug 2025 15:10:21 +0200
Subject: [PATCH] [clang][bytecode] Don't call ctor of primitive array elements

We don't do that for single primitive variables, so avoid it for
primitive array elements as well.
---
 clang/lib/AST/ByteCode/Descriptor.cpp | 46 +++++++++++++++++++++------
 1 file changed, 36 insertions(+), 10 deletions(-)

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



More information about the cfe-commits mailing list