diff options
Diffstat (limited to 'cores/arduino')
-rw-r--r-- | cores/arduino/new.cpp | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/cores/arduino/new.cpp b/cores/arduino/new.cpp index 1683594..19d80b6 100644 --- a/cores/arduino/new.cpp +++ b/cores/arduino/new.cpp @@ -18,26 +18,61 @@ #include "new.h" +// The C++ spec dicates that allocation failure should cause the +// (non-nothrow version of the) operator new to throw an exception. +// Since we expect to have exceptions disabled, it would be more +// appropriate (and probably standards-compliant) to terminate instead. +// Historically failure causes null to be returned, but this define +// allows switching to more robust terminating behaviour (that might +// become the default at some point in the future). Note that any code +// that wants null to be returned can (and should) use the nothrow +// versions of the new statement anyway and is unaffected by this. +// #define NEW_TERMINATES_ON_FAILURE + namespace std { + // Defined in abi.cpp + void terminate(); + const nothrow_t nothrow; } -void * operator new(size_t size) { +static void * new_helper(size_t size) { // Even zero-sized allocations should return a unique pointer, but // malloc does not guarantee this if (size == 0) size = 1; return malloc(size); } + +void * operator new(size_t size) { + void *res = new_helper(size); +#if defined(NEW_TERMINATES_ON_FAILURE) + if (!res) + std::terminate(); +#endif + return res; +} void * operator new[](size_t size) { return operator new(size); } void * operator new(size_t size, const std::nothrow_t tag) noexcept { +#if defined(NEW_TERMINATES_ON_FAILURE) + // Cannot call throwing operator new as standard suggests, so call + // new_helper directly then + return new_helper(size); +#else return operator new(size); +#endif } void * operator new[](size_t size, const std::nothrow_t& tag) noexcept { +#if defined(NEW_TERMINATES_ON_FAILURE) + // Cannot call throwing operator new[] as standard suggests, so call + // malloc directly then + return new_helper(size); +#else return operator new[](size); +#endif } void * operator new(size_t size, void *place) noexcept { |