From 7b15d05b62afc59a3f0d63cde6298b066270b5d1 Mon Sep 17 00:00:00 2001 From: jackson Date: Sun, 6 Oct 2024 17:19:36 -0700 Subject: [PATCH 1/2] swap size and alignment arg order in cpp new() overrides --- src/libc_override.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libc_override.cc b/src/libc_override.cc index 999583da..a0c9f6c4 100644 --- a/src/libc_override.cc +++ b/src/libc_override.cc @@ -140,7 +140,7 @@ void operator delete[](void* p, const std::nothrow_t&) noexcept { } void* operator new(size_t size, std::align_val_t alignment) noexcept(false) { - void* res = bench::malloc(static_cast(alignment), size); + void* res = bench::malloc(size, static_cast(alignment)); if (res == nullptr) { throw std::bad_alloc(); } @@ -148,7 +148,7 @@ void* operator new(size_t size, std::align_val_t alignment) noexcept(false) { } void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept { - return bench::malloc(static_cast(alignment), size); + return bench::malloc(size, static_cast(alignment)); } void operator delete(void* p, std::align_val_t alignment) noexcept { bench::free(p, /*size=*/0, static_cast(alignment)); @@ -162,7 +162,7 @@ void operator delete(void* p, size_t size, bench::free(p, size, static_cast(alignment)); } void* operator new[](size_t size, std::align_val_t alignment) noexcept(false) { - void* res = bench::malloc(static_cast(alignment), size); + void* res = bench::malloc(size, static_cast(alignment)); if (res == nullptr) { throw std::bad_alloc(); } @@ -170,7 +170,7 @@ void* operator new[](size_t size, std::align_val_t alignment) noexcept(false) { } void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept { - return bench::malloc(static_cast(alignment), size); + return bench::malloc(size, static_cast(alignment)); } void operator delete[](void* p, std::align_val_t alignment) noexcept { bench::free(p, /*size=*/0, static_cast(alignment)); From db09adce98a971069f1c2d7d04d2b1e8036428e0 Mon Sep 17 00:00:00 2001 From: jackson Date: Sun, 6 Oct 2024 17:22:23 -0700 Subject: [PATCH 2/2] make new() compliant for zero-sized allocations --- src/libc_override.cc | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/libc_override.cc b/src/libc_override.cc index a0c9f6c4..45a7c52e 100644 --- a/src/libc_override.cc +++ b/src/libc_override.cc @@ -100,8 +100,17 @@ void* (*__MALLOC_HOOK_VOLATILE __memalign_hook)(size_t, size_t, const void*) = } // extern "C" +inline constexpr size_t size_for_cpp_new(size_t size) { + // The C++ spec requires new() operators to always + // return distinct non-null pointers. + // + // Generic `malloc` implementations may return NULL for zero-sized + // allocations, so to facilitate C++ `new` we request a small size. + return size == 0 ? 1 : size; +} + void* operator new(size_t size) noexcept(false) { - void* res = bench::malloc(size); + void* res = bench::malloc(size_for_cpp_new(size)); if (res == nullptr) { throw std::bad_alloc(); } @@ -111,10 +120,10 @@ void operator delete(void* p) noexcept { bench::free(p); } void operator delete(void* p, size_t size) noexcept { - bench::free(p, size); + bench::free(p, size_for_cpp_new(size)); } void* operator new[](size_t size) noexcept(false) { - void* res = bench::malloc(size); + void* res = bench::malloc(size_for_cpp_new(size)); if (res == nullptr) { throw std::bad_alloc(); } @@ -124,13 +133,13 @@ void operator delete[](void* p) noexcept { bench::free(p); } void operator delete[](void* p, size_t size) noexcept { - bench::free(p, size); + bench::free(p, size_for_cpp_new(size)); } void* operator new(size_t size, const std::nothrow_t&) noexcept { - return bench::malloc(size); + return bench::malloc(size_for_cpp_new(size)); } void* operator new[](size_t size, const std::nothrow_t&) noexcept { - return bench::malloc(size); + return bench::malloc(size_for_cpp_new(size)); } void operator delete(void* p, const std::nothrow_t&) noexcept { bench::free(p); @@ -140,7 +149,8 @@ void operator delete[](void* p, const std::nothrow_t&) noexcept { } void* operator new(size_t size, std::align_val_t alignment) noexcept(false) { - void* res = bench::malloc(size, static_cast(alignment)); + void* res = + bench::malloc(size_for_cpp_new(size), static_cast(alignment)); if (res == nullptr) { throw std::bad_alloc(); } @@ -148,21 +158,22 @@ void* operator new(size_t size, std::align_val_t alignment) noexcept(false) { } void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept { - return bench::malloc(size, static_cast(alignment)); + return bench::malloc(size_for_cpp_new(size), static_cast(alignment)); } void operator delete(void* p, std::align_val_t alignment) noexcept { - bench::free(p, /*size=*/0, static_cast(alignment)); + bench::free(p, size_for_cpp_new(0), static_cast(alignment)); } void operator delete(void* p, std::align_val_t alignment, const std::nothrow_t&) noexcept { - bench::free(p, /*size=*/0, static_cast(alignment)); + bench::free(p, size_for_cpp_new(0), static_cast(alignment)); } void operator delete(void* p, size_t size, std::align_val_t alignment) noexcept { - bench::free(p, size, static_cast(alignment)); + bench::free(p, size_for_cpp_new(size), static_cast(alignment)); } void* operator new[](size_t size, std::align_val_t alignment) noexcept(false) { - void* res = bench::malloc(size, static_cast(alignment)); + void* res = + bench::malloc(size_for_cpp_new(size), static_cast(alignment)); if (res == nullptr) { throw std::bad_alloc(); } @@ -170,18 +181,18 @@ void* operator new[](size_t size, std::align_val_t alignment) noexcept(false) { } void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept { - return bench::malloc(size, static_cast(alignment)); + return bench::malloc(size_for_cpp_new(size), static_cast(alignment)); } void operator delete[](void* p, std::align_val_t alignment) noexcept { - bench::free(p, /*size=*/0, static_cast(alignment)); + bench::free(p, size_for_cpp_new(0), static_cast(alignment)); } void operator delete[](void* p, std::align_val_t alignment, const std::nothrow_t&) noexcept { - bench::free(p, /*size=*/0, static_cast(alignment)); + bench::free(p, size_for_cpp_new(0), static_cast(alignment)); } void operator delete[](void* p, size_t size, std::align_val_t alignment) noexcept { - bench::free(p, size, static_cast(alignment)); + bench::free(p, size_for_cpp_new(size), static_cast(alignment)); } extern "C" {