From 33dbe385cec8edd62425d7d722082dcd907d5cd3 Mon Sep 17 00:00:00 2001 From: Daniel Bertalan Date: Sat, 17 May 2025 11:22:02 +0200 Subject: [PATCH] AK: Replace `CallableWrapper::destroy()` with a destructor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, heap-allocated `CallableWrapper` objects were destroyed in a very roundabout way: `AK::Function` would call a virtual `destroy()` method, which then invoked delete manually. This was unnecessary, since `CallableWrapper` already has a virtual destructor — deleting it through a `CallableWrapperBase*` correctly calls the closure's destructor. This fixes GCC `-Wfree-nonheap-object` false positive warnings (#4721) and coincidentally removes 8 KB of vtable entries (and the corresponding relative relocations) from LibJS. --- AK/Function.h | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/AK/Function.h b/AK/Function.h index d1a8a4b900..3f929da139 100644 --- a/AK/Function.h +++ b/AK/Function.h @@ -205,7 +205,6 @@ private: virtual ~CallableWrapperBase() = default; // Note: This is not const to allow storing mutable lambdas. virtual Out call(In...) = 0; - virtual void destroy() = 0; virtual void init_and_swap(u8*, size_t) = 0; virtual void const* raw_callable() const = 0; }; @@ -226,16 +225,13 @@ private: return m_callable(forward(in)...); } - void destroy() final override + virtual ~CallableWrapper() final override { if constexpr (IsBlockClosure) { if constexpr (Detail::HaveObjcArc) m_callable = nullptr; else _Block_release(m_callable); - } else { - // This code is a bit too clever for gcc. Pinky promise we're only deleting heap objects. - AK_IGNORE_DIAGNOSTIC("-Wfree-nonheap-object", delete this); } } @@ -298,12 +294,10 @@ private: break; case FunctionKind::Outline: VERIFY(wrapper); - // This code is a bit too clever for gcc. Pinky promise we're only deleting heap objects. - AK_IGNORE_DIAGNOSTIC("-Wfree-nonheap-object", wrapper->destroy()); + delete wrapper; break; case FunctionKind::Block: VERIFY(wrapper); - wrapper->destroy(); wrapper->~CallableWrapperBase(); break; case FunctionKind::NullPointer: