Do not include 'new' standard header from gc_cpp.h by default
authorIvan Maidanski <ivmai@mail.ru>
Tue, 19 Jun 2018 07:38:55 +0000 (10:38 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 19 Jun 2018 07:38:55 +0000 (10:38 +0300)
(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
include/gc_cpp.h

index 621a316..88ffe96 100644 (file)
--- 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;
     }
 
index 64a10d2..83a8477 100644 (file)
@@ -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