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

`invokeCtor()` first memsets the memory to zero, then calls the descriptor ctor 
function. The memset is unnecessary if we're already working with zero-ed 
memory, like the one we get from `std::make_unique`.

>From e45bb95d006c6e417cf61550c1c36a82f889077d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]>
Date: Sat, 13 Jun 2026 19:57:44 +0200
Subject: [PATCH] [clang][bytecode] Add `Block::invokeCtorNoMemset()`

`invokeCtor()` first memsets the memory to zero, then calls the
descriptor ctor function. The memset is unnecessary if we're already
working with zero-ed memory, like the one we get from
`std::make_unique`.
---
 clang/lib/AST/ByteCode/DynamicAllocator.cpp | 2 +-
 clang/lib/AST/ByteCode/EvalEmitter.cpp      | 2 +-
 clang/lib/AST/ByteCode/InterpBlock.h        | 9 +++++++--
 3 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ByteCode/DynamicAllocator.cpp 
b/clang/lib/AST/ByteCode/DynamicAllocator.cpp
index 36e0bfd666b74..a3a0dcd489a76 100644
--- a/clang/lib/AST/ByteCode/DynamicAllocator.cpp
+++ b/clang/lib/AST/ByteCode/DynamicAllocator.cpp
@@ -76,7 +76,7 @@ Block *DynamicAllocator::allocate(const Descriptor *D, 
unsigned EvalID,
   auto Memory =
       std::make_unique<std::byte[]>(sizeof(Block) + D->getAllocSize());
   auto *B = new (Memory.get()) Block(EvalID, D, /*isStatic=*/false);
-  B->invokeCtor();
+  B->invokeCtorNoMemset();
 
   assert(D->getMetadataSize() == sizeof(InlineDescriptor));
   InlineDescriptor *ID = reinterpret_cast<InlineDescriptor *>(B->rawData());
diff --git a/clang/lib/AST/ByteCode/EvalEmitter.cpp 
b/clang/lib/AST/ByteCode/EvalEmitter.cpp
index a7afd3008afb8..6e986f4bcbda5 100644
--- a/clang/lib/AST/ByteCode/EvalEmitter.cpp
+++ b/clang/lib/AST/ByteCode/EvalEmitter.cpp
@@ -134,7 +134,7 @@ Scope::Local EvalEmitter::createLocal(Descriptor *D) {
   // Allocate memory for a local.
   auto Memory = std::make_unique<char[]>(sizeof(Block) + D->getAllocSize());
   auto *B = new (Memory.get()) Block(Ctx.getEvalID(), D, /*IsStatic=*/false);
-  B->invokeCtor();
+  B->invokeCtorNoMemset();
 
   // Initialize local variable inline descriptor.
   auto &Desc = B->getBlockDesc<InlineDescriptor>();
diff --git a/clang/lib/AST/ByteCode/InterpBlock.h 
b/clang/lib/AST/ByteCode/InterpBlock.h
index 4a1195ef25bbe..0d64439da78ae 100644
--- a/clang/lib/AST/ByteCode/InterpBlock.h
+++ b/clang/lib/AST/ByteCode/InterpBlock.h
@@ -136,11 +136,16 @@ class Block final {
   void invokeCtor() {
     assert(!IsInitialized);
     std::memset(rawData(), 0, Desc->getAllocSize());
-    if (Desc->CtorFn) {
+    invokeCtorNoMemset();
+  }
+  /// The same, but won't memset() the memory first to zero.
+  void invokeCtorNoMemset() {
+    assert(!IsInitialized);
+    if (Desc->CtorFn)
       Desc->CtorFn(this, data(), Desc->IsConst, Desc->IsMutable,
                    Desc->IsVolatile,
                    /*isActive=*/true, /*InUnion=*/false, Desc);
-    }
+
     IsInitialized = true;
   }
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to