This is an automated email from the ASF dual-hosted git repository.

bneradt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new c36d99a560 GCC 15: Address mismatched-new-delete in MemArena::Block 
(#12163)
c36d99a560 is described below

commit c36d99a56047b4a96e66e1bcd54a2891a4f23297
Author: Brian Neradt <brian.ner...@gmail.com>
AuthorDate: Fri Apr 4 15:43:38 2025 -0500

    GCC 15: Address mismatched-new-delete in MemArena::Block (#12163)
    
    This addresses a GCC 15 compiler warning about mismatched std operator
    new and overridden operator delete in MemArena. This patch addresses the
    warning by also overriding operator new for the MemArena::Block.
    
    This is the warning being addressed:
    
    ```
    lib/swoc/src/MemArena.cc: In member function 
‘swoc::_1_5_14::MemArena::Block* swoc::_1_5_14::MemArena::make_block(size_t)’:
    lib/swoc/src/MemArena.cc:99:44: error: ‘static void 
swoc::_1_5_14::MemArena::Block::operator delete(void*, void*)’ called on 
pointer returned from a mismatched allocation function [-Werror=mism
    atched-new-delete]
       99 |   return new (::malloc(n)) Block(free_space);
          |                                            ^
    src/ts_asf_master_fix_builds_for_fedora_42/lib/swoc/src/MemArena.cc:99:23: 
note: returned from ‘void* malloc(size_t)’
       99 |   return new (::malloc(n)) Block(free_space);
          |               ~~~~~~~~^~~
    ```
---
 lib/swoc/include/swoc/MemArena.h | 40 ++++++++++++++++++++++++++++++++++++++++
 lib/swoc/src/MemArena.cc         |  6 ++----
 2 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/lib/swoc/include/swoc/MemArena.h b/lib/swoc/include/swoc/MemArena.h
index e0b25fb2e1..f9605993d2 100644
--- a/lib/swoc/include/swoc/MemArena.h
+++ b/lib/swoc/include/swoc/MemArena.h
@@ -9,6 +9,8 @@
 
 #include <mutex>
 #include <memory>
+#include <stdexcept>
+#include <type_traits>
 #include <utility>
 #include <new>
 #if __has_include(<memory_resource>)
@@ -124,6 +126,24 @@ public:
   protected:
     friend MemArena; ///< Container.
 
+    /** A custom @c operator @c new.
+     *
+     * Compilers complain about mismatched std operator new and the custom
+     * operator delete unless this custom operator new is provided.
+     *
+     * @param block_size The implicit compiler-provided sizeof(Block), the 
object size.
+     * @param n The number of bytes the user is requesting for the backend 
storage of Block.
+     * @return Pointer to the allocated memory.
+     */
+    static void* operator new(size_t block_size, size_t n);
+
+    /** Override placement (non-allocated) @c new.
+     * @param block_size The implicit compiler-provided sizeof(Block), the 
object size. Not used.
+     * @param place Value passed to @c new.
+     * @return Pointer to the memory.
+     */
+    static void* operator new([[maybe_unused]] size_t block_size, void* place) 
noexcept;
+
     /** Override @c operator @c delete.
      *
      * This is required because the allocated memory size is larger than the 
class size which
@@ -641,6 +661,26 @@ MemArena::Block::discard() {
   return *this;
 }
 
+inline void*
+MemArena::Block::operator new(size_t block_size, size_t n)
+{
+  if (n < block_size) {
+    throw std::invalid_argument("MemArena::Block::operator new size is less 
than object size.");
+  }
+  // In theory we could use ::operator new(n) but this causes a size mismatch 
during ::operator delete.
+  // Easier to use malloc here and also override @c delete.
+  auto b = static_cast<Block *>(::malloc(n));
+  if (b == nullptr) {
+    throw std::bad_alloc();
+  }
+  return b;
+}
+
+inline void*
+MemArena::Block::operator new([[maybe_unused]] size_t block_size, void* place) 
noexcept {
+  return place;
+}
+
 inline void
 MemArena::Block::operator delete(void *ptr) noexcept {
   ::free(ptr);
diff --git a/lib/swoc/src/MemArena.cc b/lib/swoc/src/MemArena.cc
index 1d4d708ca3..8621467994 100644
--- a/lib/swoc/src/MemArena.cc
+++ b/lib/swoc/src/MemArena.cc
@@ -91,12 +91,10 @@ MemArena::make_block(size_t n) {
     n = QuarterPage{round_up(n)};
   }
 
-  // Allocate space for the Block instance and the request memory and 
construct a Block at the front.
-  // In theory this could use ::operator new(n) but this causes a size 
mismatch during ::operator delete.
-  // Easier to use malloc and override @c delete.
+  // Allocate space for the Block instance and the requested memory and 
construct a Block at the front.
   auto free_space   = n - sizeof(Block);
   _active_reserved += free_space;
-  return new (::malloc(n)) Block(free_space);
+  return new (n) Block(free_space);
 }
 
 MemSpan<void>

Reply via email to