xref: /freebsd/contrib/llvm-project/libcxx/src/new.cpp (revision 7a6dacaca14b62ca4b74406814becb87a3fefac0)
1349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
9*7a6dacacSDimitry Andric #include "include/overridable_function.h"
1006c3fb27SDimitry Andric #include <__memory/aligned_alloc.h>
11*7a6dacacSDimitry Andric #include <cstddef>
1206c3fb27SDimitry Andric #include <cstdlib>
1381ad6265SDimitry Andric #include <new>
140b57cec5SDimitry Andric 
1506c3fb27SDimitry Andric #if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_VCRUNTIME)
160b57cec5SDimitry Andric 
1706c3fb27SDimitry Andric // The code below is copied as-is into libc++abi's libcxxabi/src/stdlib_new_delete.cpp
1806c3fb27SDimitry Andric // file. The version in this file is the canonical one.
190b57cec5SDimitry Andric 
20*7a6dacacSDimitry Andric inline void __throw_bad_alloc_shim() { std::__throw_bad_alloc(); }
21*7a6dacacSDimitry Andric 
22*7a6dacacSDimitry Andric #  define _LIBCPP_ASSERT_SHIM(expr, str) _LIBCPP_ASSERT(expr, str)
23*7a6dacacSDimitry Andric 
2406c3fb27SDimitry Andric // ------------------ BEGIN COPY ------------------
250b57cec5SDimitry Andric // Implement all new and delete operators as weak definitions
260b57cec5SDimitry Andric // in this shared library, so that they can be overridden by programs
270b57cec5SDimitry Andric // that define non-weak copies of the functions.
280b57cec5SDimitry Andric 
29*7a6dacacSDimitry Andric static void* operator_new_impl(std::size_t size) {
300b57cec5SDimitry Andric   if (size == 0)
310b57cec5SDimitry Andric     size = 1;
320b57cec5SDimitry Andric   void* p;
335f757f3fSDimitry Andric   while ((p = std::malloc(size)) == nullptr) {
340b57cec5SDimitry Andric     // If malloc fails and there is a new_handler,
350b57cec5SDimitry Andric     // call it to try free up memory.
360b57cec5SDimitry Andric     std::new_handler nh = std::get_new_handler();
370b57cec5SDimitry Andric     if (nh)
380b57cec5SDimitry Andric       nh();
390b57cec5SDimitry Andric     else
400b57cec5SDimitry Andric       break;
410b57cec5SDimitry Andric   }
420b57cec5SDimitry Andric   return p;
430b57cec5SDimitry Andric }
440b57cec5SDimitry Andric 
45*7a6dacacSDimitry Andric _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC {
465f757f3fSDimitry Andric   void* p = operator_new_impl(size);
475f757f3fSDimitry Andric   if (p == nullptr)
48*7a6dacacSDimitry Andric     __throw_bad_alloc_shim();
495f757f3fSDimitry Andric   return p;
505f757f3fSDimitry Andric }
515f757f3fSDimitry Andric 
525f757f3fSDimitry Andric _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
53*7a6dacacSDimitry Andric #  ifdef _LIBCPP_HAS_NO_EXCEPTIONS
54*7a6dacacSDimitry Andric #    if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
55*7a6dacacSDimitry Andric   _LIBCPP_ASSERT_SHIM(
56*7a6dacacSDimitry Andric       !std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new)),
57*7a6dacacSDimitry Andric       "libc++ was configured with exceptions disabled and `operator new(size_t)` has been overridden, "
58*7a6dacacSDimitry Andric       "but `operator new(size_t, nothrow_t)` has not been overridden. This is problematic because "
59*7a6dacacSDimitry Andric       "`operator new(size_t, nothrow_t)` must call `operator new(size_t)`, which will terminate in case "
60*7a6dacacSDimitry Andric       "it fails to allocate, making it impossible for `operator new(size_t, nothrow_t)` to fulfill its "
61*7a6dacacSDimitry Andric       "contract (since it should return nullptr upon failure). Please make sure you override "
62*7a6dacacSDimitry Andric       "`operator new(size_t, nothrow_t)` as well.");
63*7a6dacacSDimitry Andric #    endif
64*7a6dacacSDimitry Andric 
65*7a6dacacSDimitry Andric   return operator_new_impl(size);
66*7a6dacacSDimitry Andric #  else
67e8d8bef9SDimitry Andric   void* p = nullptr;
685f757f3fSDimitry Andric   try {
690b57cec5SDimitry Andric     p = ::operator new(size);
705f757f3fSDimitry Andric   } catch (...) {
710b57cec5SDimitry Andric   }
720b57cec5SDimitry Andric   return p;
73*7a6dacacSDimitry Andric #  endif
740b57cec5SDimitry Andric }
750b57cec5SDimitry Andric 
76*7a6dacacSDimitry Andric _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new[](size_t size) _THROW_BAD_ALLOC {
77*7a6dacacSDimitry Andric   return ::operator new(size);
78*7a6dacacSDimitry Andric }
790b57cec5SDimitry Andric 
805f757f3fSDimitry Andric _LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept {
81*7a6dacacSDimitry Andric #  ifdef _LIBCPP_HAS_NO_EXCEPTIONS
82*7a6dacacSDimitry Andric #    if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
83*7a6dacacSDimitry Andric   _LIBCPP_ASSERT_SHIM(
84*7a6dacacSDimitry Andric       !std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new[])),
85*7a6dacacSDimitry Andric       "libc++ was configured with exceptions disabled and `operator new[](size_t)` has been overridden, "
86*7a6dacacSDimitry Andric       "but `operator new[](size_t, nothrow_t)` has not been overridden. This is problematic because "
87*7a6dacacSDimitry Andric       "`operator new[](size_t, nothrow_t)` must call `operator new[](size_t)`, which will terminate in case "
88*7a6dacacSDimitry Andric       "it fails to allocate, making it impossible for `operator new[](size_t, nothrow_t)` to fulfill its "
89*7a6dacacSDimitry Andric       "contract (since it should return nullptr upon failure). Please make sure you override "
90*7a6dacacSDimitry Andric       "`operator new[](size_t, nothrow_t)` as well.");
91*7a6dacacSDimitry Andric #    endif
92*7a6dacacSDimitry Andric 
93*7a6dacacSDimitry Andric   return operator_new_impl(size);
94*7a6dacacSDimitry Andric #  else
95e8d8bef9SDimitry Andric   void* p = nullptr;
965f757f3fSDimitry Andric   try {
970b57cec5SDimitry Andric     p = ::operator new[](size);
985f757f3fSDimitry Andric   } catch (...) {
990b57cec5SDimitry Andric   }
1000b57cec5SDimitry Andric   return p;
101*7a6dacacSDimitry Andric #  endif
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric 
1045f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr) noexcept { std::free(ptr); }
1050b57cec5SDimitry Andric 
1065f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr, const std::nothrow_t&) noexcept { ::operator delete(ptr); }
1070b57cec5SDimitry Andric 
1085f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr, size_t) noexcept { ::operator delete(ptr); }
1090b57cec5SDimitry Andric 
1105f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr) noexcept { ::operator delete(ptr); }
1110b57cec5SDimitry Andric 
1125f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr, const std::nothrow_t&) noexcept { ::operator delete[](ptr); }
1130b57cec5SDimitry Andric 
1145f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); }
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric #  if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
1170b57cec5SDimitry Andric 
118*7a6dacacSDimitry Andric static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) {
1190b57cec5SDimitry Andric   if (size == 0)
1200b57cec5SDimitry Andric     size = 1;
1210b57cec5SDimitry Andric   if (static_cast<size_t>(alignment) < sizeof(void*))
1220b57cec5SDimitry Andric     alignment = std::align_val_t(sizeof(void*));
123e8d8bef9SDimitry Andric 
124e8d8bef9SDimitry Andric   // Try allocating memory. If allocation fails and there is a new_handler,
125e8d8bef9SDimitry Andric   // call it to try free up memory, and try again until it succeeds, or until
126e8d8bef9SDimitry Andric   // the new_handler decides to terminate.
1270b57cec5SDimitry Andric   void* p;
1285f757f3fSDimitry Andric   while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr) {
1290b57cec5SDimitry Andric     std::new_handler nh = std::get_new_handler();
1300b57cec5SDimitry Andric     if (nh)
1310b57cec5SDimitry Andric       nh();
1325f757f3fSDimitry Andric     else
1330b57cec5SDimitry Andric       break;
1340b57cec5SDimitry Andric   }
1350b57cec5SDimitry Andric   return p;
1360b57cec5SDimitry Andric }
1370b57cec5SDimitry Andric 
138*7a6dacacSDimitry Andric _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void*
139*7a6dacacSDimitry Andric operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
1405f757f3fSDimitry Andric   void* p = operator_new_aligned_impl(size, alignment);
1415f757f3fSDimitry Andric   if (p == nullptr)
142*7a6dacacSDimitry Andric     __throw_bad_alloc_shim();
1435f757f3fSDimitry Andric   return p;
1445f757f3fSDimitry Andric }
1455f757f3fSDimitry Andric 
1465f757f3fSDimitry Andric _LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
147*7a6dacacSDimitry Andric #    ifdef _LIBCPP_HAS_NO_EXCEPTIONS
148*7a6dacacSDimitry Andric #      if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
149*7a6dacacSDimitry Andric   _LIBCPP_ASSERT_SHIM(
150*7a6dacacSDimitry Andric       !std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new)),
151*7a6dacacSDimitry Andric       "libc++ was configured with exceptions disabled and `operator new(size_t, align_val_t)` has been overridden, "
152*7a6dacacSDimitry Andric       "but `operator new(size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because "
153*7a6dacacSDimitry Andric       "`operator new(size_t, align_val_t, nothrow_t)` must call `operator new(size_t, align_val_t)`, which will "
154*7a6dacacSDimitry Andric       "terminate in case it fails to allocate, making it impossible for `operator new(size_t, align_val_t, nothrow_t)` "
155*7a6dacacSDimitry Andric       "to fulfill its contract (since it should return nullptr upon failure). Please make sure you override "
156*7a6dacacSDimitry Andric       "`operator new(size_t, align_val_t, nothrow_t)` as well.");
157*7a6dacacSDimitry Andric #      endif
158*7a6dacacSDimitry Andric 
159*7a6dacacSDimitry Andric   return operator_new_aligned_impl(size, alignment);
160*7a6dacacSDimitry Andric #    else
161e8d8bef9SDimitry Andric   void* p = nullptr;
1625f757f3fSDimitry Andric   try {
1630b57cec5SDimitry Andric     p = ::operator new(size, alignment);
1645f757f3fSDimitry Andric   } catch (...) {
1650b57cec5SDimitry Andric   }
1660b57cec5SDimitry Andric   return p;
167*7a6dacacSDimitry Andric #    endif
1680b57cec5SDimitry Andric }
1690b57cec5SDimitry Andric 
170*7a6dacacSDimitry Andric _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void*
171*7a6dacacSDimitry Andric operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
1720b57cec5SDimitry Andric   return ::operator new(size, alignment);
1730b57cec5SDimitry Andric }
1740b57cec5SDimitry Andric 
1755f757f3fSDimitry Andric _LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
176*7a6dacacSDimitry Andric #    ifdef _LIBCPP_HAS_NO_EXCEPTIONS
177*7a6dacacSDimitry Andric #      if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
178*7a6dacacSDimitry Andric   _LIBCPP_ASSERT_SHIM(
179*7a6dacacSDimitry Andric       !std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new[])),
180*7a6dacacSDimitry Andric       "libc++ was configured with exceptions disabled and `operator new[](size_t, align_val_t)` has been overridden, "
181*7a6dacacSDimitry Andric       "but `operator new[](size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because "
182*7a6dacacSDimitry Andric       "`operator new[](size_t, align_val_t, nothrow_t)` must call `operator new[](size_t, align_val_t)`, which will "
183*7a6dacacSDimitry Andric       "terminate in case it fails to allocate, making it impossible for `operator new[](size_t, align_val_t, "
184*7a6dacacSDimitry Andric       "nothrow_t)` to fulfill its contract (since it should return nullptr upon failure). Please make sure you "
185*7a6dacacSDimitry Andric       "override "
186*7a6dacacSDimitry Andric       "`operator new[](size_t, align_val_t, nothrow_t)` as well.");
187*7a6dacacSDimitry Andric #      endif
188*7a6dacacSDimitry Andric 
189*7a6dacacSDimitry Andric   return operator_new_aligned_impl(size, alignment);
190*7a6dacacSDimitry Andric #    else
191e8d8bef9SDimitry Andric   void* p = nullptr;
1925f757f3fSDimitry Andric   try {
1930b57cec5SDimitry Andric     p = ::operator new[](size, alignment);
1945f757f3fSDimitry Andric   } catch (...) {
1950b57cec5SDimitry Andric   }
1960b57cec5SDimitry Andric   return p;
197*7a6dacacSDimitry Andric #    endif
1980b57cec5SDimitry Andric }
1990b57cec5SDimitry Andric 
2005f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t) noexcept { std::__libcpp_aligned_free(ptr); }
2010b57cec5SDimitry Andric 
2025f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept {
2030b57cec5SDimitry Andric   ::operator delete(ptr, alignment);
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric 
2065f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept {
2070b57cec5SDimitry Andric   ::operator delete(ptr, alignment);
2080b57cec5SDimitry Andric }
2090b57cec5SDimitry Andric 
2105f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr, std::align_val_t alignment) noexcept {
2110b57cec5SDimitry Andric   ::operator delete(ptr, alignment);
2120b57cec5SDimitry Andric }
2130b57cec5SDimitry Andric 
2145f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept {
2150b57cec5SDimitry Andric   ::operator delete[](ptr, alignment);
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric 
2185f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr, size_t, std::align_val_t alignment) noexcept {
2190b57cec5SDimitry Andric   ::operator delete[](ptr, alignment);
2200b57cec5SDimitry Andric }
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric #  endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
22306c3fb27SDimitry Andric // ------------------ END COPY ------------------
22406c3fb27SDimitry Andric 
22506c3fb27SDimitry Andric #endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME
226