From 2ce94e20e884063240e70f21e706d73b8281f604 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Tue, 19 Jun 2018 10:38:55 +0300 Subject: [PATCH] Do not include 'new' standard header from gc_cpp.h by default (fix of commit cb1194d17) * gc_cpp.cc: Include gc.h (before "new") and "new" standard header (before gc_cpp.h). * gc_cpp.cc (GC_ALLOCATOR_THROW_OR_ABORT): New macro (the same definition as in gc_allocator.h). * gc_cpp.cc (GC_throw_bad_alloc): New API function definition. * gc_cpp.cc [!GC_NEW_DELETE_THROW_NOT_NEEDED] (GC_NEW_DELETE_NEED_THROW): Do not define if _MSC_VER or __DMC__. * gc_cpp.cc [!_MSC_VER && !__DMC__] (new, new[]): Replace GC_OP_NEW_OOM_CHECK(obj) to if(!obj)GC_ALLOCATOR_THROW_OR_ABORT(). * gc_cpp.h: Include "new" standard header only if GC_INCLUDE_NEW and !GC_NEW_ABORTS_ON_OOM and !_LIBCPP_NO_EXCEPTIONS. * gc_cpp.h [!GC_NEW_ABORTS_ON_OOM && !_LIBCPP_NO_EXCEPTIONS && !GC_INCLUDE_NEW] (GC_throw_bad_alloc): Declare API function. * gc_cpp.h [!GC_NEW_ABORTS_ON_OOM && !_LIBCPP_NO_EXCEPTIONS && !GC_INCLUDE_NEW] (GC_OP_NEW_OOM_CHECK): Call GC_throw_bad_alloc() instead of throw std::bad_alloc; do not use do-while(0) (to eliminate VC++ warning that the expression is always false). --- gc_cpp.cc | 30 +++++++++++++++++++++++------- include/gc_cpp.h | 15 +++++++++------ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/gc_cpp.cc b/gc_cpp.cc index 621a3165..88ffe96e 100644 --- a/gc_cpp.cc +++ b/gc_cpp.cc @@ -27,16 +27,30 @@ built-in "new" and "delete". # define GC_BUILD #endif -#include "gc_cpp.h" +#include "gc.h" -#if !defined(GC_NEW_DELETE_THROW_NOT_NEEDED) \ - && !defined(GC_NEW_DELETE_NEED_THROW) && GC_GNUC_PREREQ(4, 2) \ - && (__cplusplus < 201103L || defined(__clang__)) -# define GC_NEW_DELETE_NEED_THROW +#include // for bad_alloc, precedes include of gc_cpp.h + +#include "gc_cpp.h" // for GC_OPERATOR_NEW_ARRAY, GC_NOEXCEPT + +#if defined(GC_NEW_ABORTS_ON_OOM) || defined(_LIBCPP_NO_EXCEPTIONS) +# define GC_ALLOCATOR_THROW_OR_ABORT() GC_abort_on_oom() +#else +# define GC_ALLOCATOR_THROW_OR_ABORT() throw std::bad_alloc() #endif +GC_API void GC_CALL GC_throw_bad_alloc() { + GC_ALLOCATOR_THROW_OR_ABORT(); +} + #if !defined(_MSC_VER) && !defined(__DMC__) +# if !defined(GC_NEW_DELETE_THROW_NOT_NEEDED) \ + && !defined(GC_NEW_DELETE_NEED_THROW) && GC_GNUC_PREREQ(4, 2) \ + && (__cplusplus < 201103L || defined(__clang__)) +# define GC_NEW_DELETE_NEED_THROW +# endif + # ifdef GC_NEW_DELETE_NEED_THROW # define GC_DECL_NEW_THROW throw(std::bad_alloc) # else @@ -45,7 +59,8 @@ built-in "new" and "delete". void* operator new(size_t size) GC_DECL_NEW_THROW { void* obj = GC_MALLOC_UNCOLLECTABLE(size); - GC_OP_NEW_OOM_CHECK(obj); + if (0 == obj) + GC_ALLOCATOR_THROW_OR_ABORT(); return obj; } @@ -56,7 +71,8 @@ built-in "new" and "delete". # if defined(GC_OPERATOR_NEW_ARRAY) && !defined(CPPCHECK) void* operator new[](size_t size) GC_DECL_NEW_THROW { void* obj = GC_MALLOC_UNCOLLECTABLE(size); - GC_OP_NEW_OOM_CHECK(obj); + if (0 == obj) + GC_ALLOCATOR_THROW_OR_ABORT(); return obj; } diff --git a/include/gc_cpp.h b/include/gc_cpp.h index 64a10d25..83a8477d 100644 --- a/include/gc_cpp.h +++ b/include/gc_cpp.h @@ -141,7 +141,6 @@ by UseGC. GC is an alias for UseGC, unless GC_NAME_CONFLICT is defined. ****************************************************************************/ #include "gc.h" -#include // for bad_alloc #ifdef GC_NAMESPACE # define GC_NS_QUALIFY(T) boehmgc::T @@ -190,13 +189,17 @@ by UseGC. GC is an alias for UseGC, unless GC_NAME_CONFLICT is defined. # endif #endif // !GC_NOEXCEPT -#if !defined(GC_NEW_ABORTS_ON_OOM) && !defined(_LIBCPP_NO_EXCEPTIONS) -# define GC_OP_NEW_OOM_CHECK(obj) \ - do { if (!(obj)) throw std::bad_alloc(); } while (0) -#else +#if defined(GC_NEW_ABORTS_ON_OOM) || defined(_LIBCPP_NO_EXCEPTIONS) # define GC_OP_NEW_OOM_CHECK(obj) \ do { if (!(obj)) GC_abort_on_oom(); } while (0) -#endif // !GC_NEW_ABORTS_ON_OOM +#elif defined(GC_INCLUDE_NEW) +# include // for bad_alloc +# define GC_OP_NEW_OOM_CHECK(obj) if (obj) {} else throw std::bad_alloc() +#else + // "new" header is not included, so bad_alloc cannot be thrown directly. + GC_API void GC_CALL GC_throw_bad_alloc(); +# define GC_OP_NEW_OOM_CHECK(obj) if (obj) {} else GC_throw_bad_alloc() +#endif // !GC_NEW_ABORTS_ON_OOM && !GC_INCLUDE_NEW #ifdef GC_NAMESPACE namespace boehmgc -- 2.50.1