diff --git a/libcxx/src/new.cpp b/libcxx/src/new.cpp index a1c9be6107bee6..033bba5c1fc95b 100644 --- a/libcxx/src/new.cpp +++ b/libcxx/src/new.cpp @@ -20,7 +20,7 @@ // in this shared library, so that they can be overridden by programs // that define non-weak copies of the functions. -_LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC { +static void* operator_new_impl(std::size_t size) noexcept { if (size == 0) size = 1; void* p; @@ -31,15 +31,20 @@ _LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC { if (nh) nh(); else -# ifndef _LIBCPP_HAS_NO_EXCEPTIONS - throw std::bad_alloc(); -# else break; -# endif } return p; } +_LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC { + void* p = operator_new_impl(size); +# ifndef _LIBCPP_HAS_NO_EXCEPTIONS + if (p == nullptr) + throw std::bad_alloc(); +# endif + return p; +} + _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept { void* p = nullptr; # ifndef _LIBCPP_HAS_NO_EXCEPTIONS @@ -82,7 +87,7 @@ _LIBCPP_WEAK void operator delete[](void* ptr, size_t) noexcept { ::operator del # if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) -_LIBCPP_WEAK void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { +static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) noexcept { if (size == 0) size = 1; if (static_cast(alignment) < sizeof(void*)) @@ -91,25 +96,26 @@ _LIBCPP_WEAK void* operator new(std::size_t size, std::align_val_t alignment) _T // Try allocating memory. If allocation fails and there is a new_handler, // call it to try free up memory, and try again until it succeeds, or until // the new_handler decides to terminate. - // - // If allocation fails and there is no new_handler, we throw bad_alloc - // (or return nullptr if exceptions are disabled). void* p; while ((p = std::__libcpp_aligned_alloc(static_cast(alignment), size)) == nullptr) { std::new_handler nh = std::get_new_handler(); if (nh) nh(); - else { -# ifndef _LIBCPP_HAS_NO_EXCEPTIONS - throw std::bad_alloc(); -# else + else break; -# endif - } } return p; } +_LIBCPP_WEAK void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { + void* p = operator_new_aligned_impl(size, alignment); +# ifndef _LIBCPP_HAS_NO_EXCEPTIONS + if (p == nullptr) + throw std::bad_alloc(); +# endif + return p; +} + _LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept { void* p = nullptr; # ifndef _LIBCPP_HAS_NO_EXCEPTIONS diff --git a/libcxxabi/src/stdlib_new_delete.cpp b/libcxxabi/src/stdlib_new_delete.cpp index 71c98793cae409..6c9990f063dde6 100644 --- a/libcxxabi/src/stdlib_new_delete.cpp +++ b/libcxxabi/src/stdlib_new_delete.cpp @@ -30,8 +30,7 @@ // in this shared library, so that they can be overridden by programs // that define non-weak copies of the functions. -_LIBCPP_WEAK -void* operator new(std::size_t size) _THROW_BAD_ALLOC { +static void* operator_new_impl(std::size_t size) noexcept { if (size == 0) size = 1; void* p; @@ -42,15 +41,21 @@ void* operator new(std::size_t size) _THROW_BAD_ALLOC { if (nh) nh(); else -#ifndef _LIBCPP_HAS_NO_EXCEPTIONS - throw std::bad_alloc(); -#else break; -#endif } return p; } +_LIBCPP_WEAK +void* operator new(std::size_t size) _THROW_BAD_ALLOC { + void* p = operator_new_impl(size); +#ifndef _LIBCPP_HAS_NO_EXCEPTIONS + if (p == nullptr) + throw std::bad_alloc(); +#endif + return p; +} + _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept { void* p = nullptr; @@ -102,8 +107,7 @@ void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); } #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) -_LIBCPP_WEAK -void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { +static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) noexcept { if (size == 0) size = 1; if (static_cast(alignment) < sizeof(void*)) @@ -112,25 +116,27 @@ void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLO // Try allocating memory. If allocation fails and there is a new_handler, // call it to try free up memory, and try again until it succeeds, or until // the new_handler decides to terminate. - // - // If allocation fails and there is no new_handler, we throw bad_alloc - // (or return nullptr if exceptions are disabled). void* p; while ((p = std::__libcpp_aligned_alloc(static_cast(alignment), size)) == nullptr) { std::new_handler nh = std::get_new_handler(); if (nh) nh(); - else { -# ifndef _LIBCPP_HAS_NO_EXCEPTIONS - throw std::bad_alloc(); -# else + else break; -# endif - } } return p; } +_LIBCPP_WEAK +void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { + void* p = operator_new_aligned_impl(size, alignment); +# ifndef _LIBCPP_HAS_NO_EXCEPTIONS + if (p == nullptr) + throw std::bad_alloc(); +# endif + return p; +} + _LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept { void* p = nullptr;