diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2018-06-01 11:29:41 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2018-06-01 11:40:54 +0300 |
commit | cb1194d17e4eb20a86b556ba7940a151a7a42a61 (patch) | |
tree | 040a9fdf664f8cc2542750ec1ab1b172179b1b90 /gc_cpp.cc | |
parent | b6afec3039e97ffcc2fc90a42877c1394700229d (diff) | |
download | bdwgc-cb1194d17e4eb20a86b556ba7940a151a7a42a61.tar.gz |
Never return null pointer by C++ operator new (gc_cpp)
Now, in case of the allocation failure, new and new[] operators throw
bad_alloc (or abort the application if an ancient compiler is used).
* gc_cpp.cc (GC_NEW_DELETE_NEED_THROW): Remove.
* gc_cpp.cc (GC_DECL_NEW_THROW, GC_DECL_DELETE_THROW): Move macro
definition to gc_cpp.h.
* gc_cpp.cc [GC_NEW_DELETE_NEED_THROW]: Do not include "new" header.
* gc_cpp.cc [!_MSC_VER] (operator new): Call GC_OP_NEW_OOM_CHECK() for
the allocation result.
* gc_cpp.cc [!_MSC_VER && GC_OPERATOR_NEW_ARRAY && !CPPCHECK]
(operator new[]): Likewise.
* include/gc.h (GC_abort_on_oom): Declare new API function.
* include/gc_cpp.h [!GC_NEW_DELETE_THROW_NOT_NEEDED
&& (GC_GNUC_PREREQ(4,2) || __BORLANDC__>=0x0550 || _MSC_VER>1020
|| __WATCOMC__>=1050)] (GC_NEW_DELETE_NEED_THROW):
Define macro.
* include/gc_cpp.h [GC_NEW_DELETE_NEED_THROW]: Include "new" header.
* include/gc_cpp.h (GC_OP_NEW_OOM_CHECK): New internal macro (throws
bad_alloc or cals GC_abort_on_oom).
* include/gc_cpp.h (gc::new(size_t), gc::new(size_t,GCPlacement), new):
Add GC_DECL_NEW_THROW; call GC_OP_NEW_OOM_CHECK() for the allocation
result.
* include/gc_cpp.h [GC_OPERATOR_NEW_ARRAY] (gc::new[](size_t),
gc::new[](size_t,GCPlacement, new[]): Likewise.
* misc.c (GC_abort_on_oom): Implement function.
* tests/test.c [CPPCHECK] (main): Call UNTESTED(GC_abort_on_oom).
Diffstat (limited to 'gc_cpp.cc')
-rw-r--r-- | gc_cpp.cc | 21 |
1 files changed, 6 insertions, 15 deletions
@@ -29,23 +29,12 @@ built-in "new" and "delete". #include "gc_cpp.h" -#if GC_GNUC_PREREQ(4, 2) && !defined(GC_NEW_DELETE_NEED_THROW) -# define GC_NEW_DELETE_NEED_THROW -#endif - -#ifdef GC_NEW_DELETE_NEED_THROW -# include <new> /* for std::bad_alloc */ -# define GC_DECL_NEW_THROW throw(std::bad_alloc) -# define GC_DECL_DELETE_THROW throw() -#else -# define GC_DECL_NEW_THROW /* empty */ -# define GC_DECL_DELETE_THROW /* empty */ -#endif // !GC_NEW_DELETE_NEED_THROW - #ifndef _MSC_VER void* operator new(size_t size) GC_DECL_NEW_THROW { - return GC_MALLOC_UNCOLLECTABLE(size); + void* obj = GC_MALLOC_UNCOLLECTABLE(size); + GC_OP_NEW_OOM_CHECK(obj); + return obj; } void operator delete(void* obj) GC_DECL_DELETE_THROW { @@ -54,7 +43,9 @@ built-in "new" and "delete". # if defined(GC_OPERATOR_NEW_ARRAY) && !defined(CPPCHECK) void* operator new[](size_t size) GC_DECL_NEW_THROW { - return GC_MALLOC_UNCOLLECTABLE(size); + void* obj = GC_MALLOC_UNCOLLECTABLE(size); + GC_OP_NEW_OOM_CHECK(obj); + return obj; } void operator delete[](void* obj) GC_DECL_DELETE_THROW { |