summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2018-06-19 10:38:55 +0300
committerIvan Maidanski <ivmai@mail.ru>2018-06-19 10:38:55 +0300
commit2ce94e20e884063240e70f21e706d73b8281f604 (patch)
treee2247a9137c2bde4108116f44f631ebda92c28cc
parent8595c0849801cf4eb053d3b3182cf0a883a4ad66 (diff)
downloadbdwgc-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.cc30
-rw-r--r--include/gc_cpp.h15
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 <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