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

If we don't have any (live) dynamic allocations, we can save ourselves the work 
of checking all the pointers in the returned value.

Also move the `getAllocator()` call in `Free()` further down so we don' 
unnecessarily create a dynamic allocator.

>From 6d0727140e45b548c1811d05e60d938ecdbf9cb0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]>
Date: Sun, 20 Sep 2026 07:13:10 +0200
Subject: [PATCH] hasDynamicAllocator

---
 clang/lib/AST/ByteCode/EvaluationResult.cpp | 3 +++
 clang/lib/AST/ByteCode/Interp.cpp           | 5 ++---
 clang/lib/AST/ByteCode/InterpState.h        | 4 +++-
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ByteCode/EvaluationResult.cpp 
b/clang/lib/AST/ByteCode/EvaluationResult.cpp
index 09b1eb822b13e2..905cd8cf93c645 100644
--- a/clang/lib/AST/ByteCode/EvaluationResult.cpp
+++ b/clang/lib/AST/ByteCode/EvaluationResult.cpp
@@ -246,6 +246,9 @@ static void collectBlocks(PtrView Ptr,
 bool EvaluationResult::checkDynamicAllocations(InterpState &S,
                                                const Pointer &Ptr,
                                                SourceInfo Info) {
+  if (!S.hasDynamicAllocations())
+    return true;
+
   if (!Ptr.isBlockPointer())
     return true;
   // Collect all blocks that this pointer (transitively) points to and
diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index 49ebcc789b7dd2..da192d254919a8 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1474,8 +1474,6 @@ bool Free(InterpState &S, CodePtr OpPC, bool 
DeleteIsArrayForm,
   if (!CheckDynamicMemoryAllocation(S, OpPC))
     return false;
 
-  DynamicAllocator &Allocator = S.getAllocator();
-
   const Expr *Source = nullptr;
   const Block *BlockToDelete = nullptr;
   {
@@ -1500,7 +1498,7 @@ bool Free(InterpState &S, CodePtr OpPC, bool 
DeleteIsArrayForm,
     // Check that new[]/delete[] or new/delete were used, not a mixture.
     const Descriptor *BlockDesc = BlockToDelete->getDescriptor();
     if (std::optional<DynamicAllocator::Form> AllocForm =
-            Allocator.getAllocationForm(Source)) {
+            S.getAllocator().getAllocationForm(Source)) {
       DynamicAllocator::Form DeleteForm =
           DeleteIsArrayForm ? DynamicAllocator::Form::Array
                             : DynamicAllocator::Form::NonArray;
@@ -1560,6 +1558,7 @@ bool Free(InterpState &S, CodePtr OpPC, bool 
DeleteIsArrayForm,
   if (!RunDestructors(S, OpPC, BlockToDelete))
     return false;
 
+  DynamicAllocator &Allocator = S.getAllocator();
   if (!Allocator.deallocate(Source, BlockToDelete)) {
     // Nothing has been deallocated, this must be a double-delete.
     const SourceInfo &Loc = S.Current->getSource(OpPC);
diff --git a/clang/lib/AST/ByteCode/InterpState.h 
b/clang/lib/AST/ByteCode/InterpState.h
index 920197d8021c06..b03679ace8eb5a 100644
--- a/clang/lib/AST/ByteCode/InterpState.h
+++ b/clang/lib/AST/ByteCode/InterpState.h
@@ -82,9 +82,11 @@ class InterpState final : public State {
     if (!Alloc) {
       Alloc = std::make_unique<DynamicAllocator>();
     }
-
     return *Alloc;
   }
+  bool hasDynamicAllocations() const {
+    return Alloc && Alloc->hasAllocations();
+  }
 
   /// Diagnose any dynamic allocations that haven't been freed yet.
   /// Will return \c false if there were any allocations to diagnose,

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

Reply via email to