[libcxx-commits] [libcxx] e494a96 - [libc++][NFC] Refactor the core logic of operator new into helper functions (#69407)

via libcxx-commits libcxx-commits at lists.llvm.org
Wed Oct 18 11:33:10 PDT 2023


Author: Louis Dionne
Date: 2023-10-18T11:33:05-07:00
New Revision: e494a96a69050c7401828f2d5199e1419d3ea55e

URL: https://github.com/llvm/llvm-project/commit/e494a96a69050c7401828f2d5199e1419d3ea55e
DIFF: https://github.com/llvm/llvm-project/commit/e494a96a69050c7401828f2d5199e1419d3ea55e.diff

LOG: [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.

Added: 
    

Modified: 
    libcxx/src/new.cpp
    libcxxabi/src/stdlib_new_delete.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/src/new.cpp b/libcxx/src/new.cpp
index a1c9be6107bee62..033bba5c1fc95b6 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<size_t>(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<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

diff  --git a/libcxxabi/src/stdlib_new_delete.cpp b/libcxxabi/src/stdlib_new_delete.cpp
index 71c98793cae4093..6c9990f063dde66 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<size_t>(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<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;


        


More information about the libcxx-commits mailing list