diff options
author | Louis Dionne <ldionne.2@gmail.com> | 2023-10-18 11:33:05 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-18 11:33:05 -0700 |
commit | e494a96a69050c7401828f2d5199e1419d3ea55e (patch) | |
tree | 58a9c6a3d649e3fb188376f564679bbc20fdd294 /libcxxabi | |
parent | 84f398af74f389febc2ebfa39d02c14bba9100dc (diff) | |
download | llvm-e494a96a69050c7401828f2d5199e1419d3ea55e.zip llvm-e494a96a69050c7401828f2d5199e1419d3ea55e.tar.gz llvm-e494a96a69050c7401828f2d5199e1419d3ea55e.tar.bz2 |
[libc++][NFC] Refactor the core logic of operator new into helper functions (#69407)
This will make it easier to implement new(nothrow) without calling the
throwing version of new when exceptions are disabled. See
https://llvm.org/D150610 for the full discussion.
Diffstat (limited to 'libcxxabi')
-rw-r--r-- | libcxxabi/src/stdlib_new_delete.cpp | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/libcxxabi/src/stdlib_new_delete.cpp b/libcxxabi/src/stdlib_new_delete.cpp index 71c9879..6c9990f 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,16 +41,22 @@ 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 @@ -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<size_t>(alignment) < sizeof(void*)) @@ -112,26 +116,28 @@ 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<std::size_t>(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 |