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
