diff options
-rw-r--r-- | gc_cpp.cc | 30 | ||||
-rw-r--r-- | include/gc_cpp.h | 15 |
2 files changed, 32 insertions, 13 deletions
@@ -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 <new> // 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 <new> // 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 <new> // 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 |