# 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
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;
}
# 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;
}
****************************************************************************/
#include "gc.h"
-#include <new> // for bad_alloc
#ifdef GC_NAMESPACE
# define GC_NS_QUALIFY(T) boehmgc::T
# 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