diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2018-06-19 10:38:55 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2018-06-19 10:38:55 +0300 |
commit | 2ce94e20e884063240e70f21e706d73b8281f604 (patch) | |
tree | e2247a9137c2bde4108116f44f631ebda92c28cc | |
parent | 8595c0849801cf4eb053d3b3182cf0a883a4ad66 (diff) | |
download | bdwgc-2ce94e20e884063240e70f21e706d73b8281f604.tar.gz |
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).
-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 |