diff --git a/CMakeLists.txt b/CMakeLists.txt index 8127e0965..efbf17b62 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,7 @@ option(MI_SECURE "Use full security mitigations (like guard pages, al option(MI_DEBUG_FULL "Use full internal heap invariant checking in DEBUG mode (expensive)" OFF) option(MI_PADDING "Enable padding to detect heap block overflow (used only in DEBUG mode)" ON) option(MI_OVERRIDE "Override the standard malloc interface (e.g. define entry points for malloc() etc)" ON) +option(MI_OVERRIDE_CXX "Override the standard new/delete C++ interface" ${MI_OVERRIDE}) option(MI_XMALLOC "Enable abort() call on memory allocation failure by default" OFF) option(MI_SHOW_ERRORS "Show error and warning messages by default (only enabled by default in DEBUG mode)" OFF) option(MI_USE_CXX "Use the C++ compiler to compile the library (instead of the C compiler)" OFF) @@ -411,3 +412,18 @@ if (MI_OVERRIDE) endif() endif() endif() + +if (MI_OVERRIDE_CXX) + if (MI_BUILD_SHARED) + target_compile_definitions(mimalloc PRIVATE MI_MALLOC_OVERRIDE_CXX) + endif() + if(NOT WIN32) + # It is only possible to override malloc on Windows when building as a DLL. + if (MI_BUILD_STATIC) + target_compile_definitions(mimalloc-static PRIVATE MI_MALLOC_OVERRIDE_CXX) + endif() + if (MI_BUILD_OBJECT) + target_compile_definitions(mimalloc-obj PRIVATE MI_MALLOC_OVERRIDE_CXX) + endif() + endif() +endif() diff --git a/src/alloc-override.c b/src/alloc-override.c index e29cb4b23..28fadd7a6 100644 --- a/src/alloc-override.c +++ b/src/alloc-override.c @@ -22,8 +22,10 @@ mi_decl_externc size_t malloc_size(const void* p); mi_decl_externc size_t malloc_good_size(size_t size); #endif +#if defined(MI_MALLOC_OVERRIDE_CXX) // helper definition for C override of C++ new typedef struct mi_nothrow_s { int _tag; } mi_nothrow_t; +#endif // ------------------------------------------------------ // Override system malloc @@ -92,6 +94,7 @@ typedef struct mi_nothrow_s { int _tag; } mi_nothrow_t; #endif }; + #if defined(MI_MALLOC_OVERRIDE_CXX) #ifdef __cplusplus extern "C" { #endif @@ -117,6 +120,7 @@ typedef struct mi_nothrow_s { int _tag; } mi_nothrow_t; MI_INTERPOSE_FUN(_ZnwmRKSt9nothrow_t,mi_new_nothrow), MI_INTERPOSE_FUN(_ZnamRKSt9nothrow_t,mi_new_nothrow), }; + #endif #elif defined(_MSC_VER) // cannot override malloc unless using a dll. @@ -138,7 +142,7 @@ typedef struct mi_nothrow_s { int _tag; } mi_nothrow_t; // This is not really necessary as they usually call // malloc/free anyway, but it improves performance. // ------------------------------------------------------ -#ifdef __cplusplus +#ifdef defined(MI_MALLOC_OVERRIDE_CXX) && __cplusplus // ------------------------------------------------------ // With a C++ compiler we override the new/delete operators. // see @@ -175,7 +179,7 @@ typedef struct mi_nothrow_s { int _tag; } mi_nothrow_t; void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast(al)); } #endif -#elif (defined(__GNUC__) || defined(__clang__)) +#elif defined(MI_MALLOC_OVERRIDE_CXX) && (defined(__GNUC__) || defined(__clang__)) // ------------------------------------------------------ // Override by defining the mangled C++ names of the operators (as // used by GCC and CLang). @@ -212,7 +216,7 @@ typedef struct mi_nothrow_s { int _tag; } mi_nothrow_t; #else #error "define overloads for new/delete for this platform (just for performance, can be skipped)" #endif -#endif // __cplusplus +#endif // defined(MI_MALLOC_OVERRIDE_CXX) && __cplusplus // ------------------------------------------------------ // Further Posix & Unix functions definitions