Bump version to 19.1.0 (final)
[llvm-project.git] / libcxxabi / src / stdlib_new_delete.cpp
blobb802559d479e2c0ec8dc2e4f119069c361564a1f
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "__cxxabi_config.h"
10 #include "abort_message.h"
11 #include "include/overridable_function.h" // from libc++
12 #include <__memory/aligned_alloc.h>
13 #include <cstddef>
14 #include <cstdlib>
15 #include <new>
17 // Perform a few sanity checks on libc++ and libc++abi macros to ensure that
18 // the code below can be an exact copy of the code in libcxx/src/new.cpp.
19 #if !defined(_THROW_BAD_ALLOC)
20 # error The _THROW_BAD_ALLOC macro should be already defined by libc++
21 #endif
23 #ifndef _LIBCPP_WEAK
24 # error The _LIBCPP_WEAK macro should be already defined by libc++
25 #endif
27 #if defined(_LIBCXXABI_NO_EXCEPTIONS) != defined(_LIBCPP_HAS_NO_EXCEPTIONS)
28 # error libc++ and libc++abi seem to disagree on whether exceptions are enabled
29 #endif
31 inline void __throw_bad_alloc_shim() {
32 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
33 throw std::bad_alloc();
34 #else
35 abort_message("bad_alloc was thrown in -fno-exceptions mode");
36 #endif
39 #define _LIBCPP_ASSERT_SHIM(expr, str) \
40 do { \
41 if (!expr) \
42 abort_message(str); \
43 } while (false)
45 // ------------------ BEGIN COPY ------------------
46 // Implement all new and delete operators as weak definitions
47 // in this shared library, so that they can be overridden by programs
48 // that define non-weak copies of the functions.
50 static void* operator_new_impl(std::size_t size) {
51 if (size == 0)
52 size = 1;
53 void* p;
54 while ((p = std::malloc(size)) == nullptr) {
55 // If malloc fails and there is a new_handler,
56 // call it to try free up memory.
57 std::new_handler nh = std::get_new_handler();
58 if (nh)
59 nh();
60 else
61 break;
63 return p;
66 _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC {
67 void* p = operator_new_impl(size);
68 if (p == nullptr)
69 __throw_bad_alloc_shim();
70 return p;
73 _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
74 #ifdef _LIBCPP_HAS_NO_EXCEPTIONS
75 # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
76 _LIBCPP_ASSERT_SHIM(
77 !std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new)),
78 "libc++ was configured with exceptions disabled and `operator new(size_t)` has been overridden, "
79 "but `operator new(size_t, nothrow_t)` has not been overridden. This is problematic because "
80 "`operator new(size_t, nothrow_t)` must call `operator new(size_t)`, which will terminate in case "
81 "it fails to allocate, making it impossible for `operator new(size_t, nothrow_t)` to fulfill its "
82 "contract (since it should return nullptr upon failure). Please make sure you override "
83 "`operator new(size_t, nothrow_t)` as well.");
84 # endif
86 return operator_new_impl(size);
87 #else
88 void* p = nullptr;
89 try {
90 p = ::operator new(size);
91 } catch (...) {
93 return p;
94 #endif
97 _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new[](size_t size) _THROW_BAD_ALLOC {
98 return ::operator new(size);
101 _LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept {
102 #ifdef _LIBCPP_HAS_NO_EXCEPTIONS
103 # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
104 _LIBCPP_ASSERT_SHIM(
105 !std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new[])),
106 "libc++ was configured with exceptions disabled and `operator new[](size_t)` has been overridden, "
107 "but `operator new[](size_t, nothrow_t)` has not been overridden. This is problematic because "
108 "`operator new[](size_t, nothrow_t)` must call `operator new[](size_t)`, which will terminate in case "
109 "it fails to allocate, making it impossible for `operator new[](size_t, nothrow_t)` to fulfill its "
110 "contract (since it should return nullptr upon failure). Please make sure you override "
111 "`operator new[](size_t, nothrow_t)` as well.");
112 # endif
114 return operator_new_impl(size);
115 #else
116 void* p = nullptr;
117 try {
118 p = ::operator new[](size);
119 } catch (...) {
121 return p;
122 #endif
125 _LIBCPP_WEAK void operator delete(void* ptr) noexcept { std::free(ptr); }
127 _LIBCPP_WEAK void operator delete(void* ptr, const std::nothrow_t&) noexcept { ::operator delete(ptr); }
129 _LIBCPP_WEAK void operator delete(void* ptr, size_t) noexcept { ::operator delete(ptr); }
131 _LIBCPP_WEAK void operator delete[](void* ptr) noexcept { ::operator delete(ptr); }
133 _LIBCPP_WEAK void operator delete[](void* ptr, const std::nothrow_t&) noexcept { ::operator delete[](ptr); }
135 _LIBCPP_WEAK void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); }
137 #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
139 static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) {
140 if (size == 0)
141 size = 1;
142 if (static_cast<size_t>(alignment) < sizeof(void*))
143 alignment = std::align_val_t(sizeof(void*));
145 // Try allocating memory. If allocation fails and there is a new_handler,
146 // call it to try free up memory, and try again until it succeeds, or until
147 // the new_handler decides to terminate.
148 void* p;
149 while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr) {
150 std::new_handler nh = std::get_new_handler();
151 if (nh)
152 nh();
153 else
154 break;
156 return p;
159 _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void*
160 operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
161 void* p = operator_new_aligned_impl(size, alignment);
162 if (p == nullptr)
163 __throw_bad_alloc_shim();
164 return p;
167 _LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
168 # ifdef _LIBCPP_HAS_NO_EXCEPTIONS
169 # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
170 _LIBCPP_ASSERT_SHIM(
171 !std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new)),
172 "libc++ was configured with exceptions disabled and `operator new(size_t, align_val_t)` has been overridden, "
173 "but `operator new(size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because "
174 "`operator new(size_t, align_val_t, nothrow_t)` must call `operator new(size_t, align_val_t)`, which will "
175 "terminate in case it fails to allocate, making it impossible for `operator new(size_t, align_val_t, nothrow_t)` "
176 "to fulfill its contract (since it should return nullptr upon failure). Please make sure you override "
177 "`operator new(size_t, align_val_t, nothrow_t)` as well.");
178 # endif
180 return operator_new_aligned_impl(size, alignment);
181 # else
182 void* p = nullptr;
183 try {
184 p = ::operator new(size, alignment);
185 } catch (...) {
187 return p;
188 # endif
191 _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void*
192 operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
193 return ::operator new(size, alignment);
196 _LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
197 # ifdef _LIBCPP_HAS_NO_EXCEPTIONS
198 # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION
199 _LIBCPP_ASSERT_SHIM(
200 !std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new[])),
201 "libc++ was configured with exceptions disabled and `operator new[](size_t, align_val_t)` has been overridden, "
202 "but `operator new[](size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because "
203 "`operator new[](size_t, align_val_t, nothrow_t)` must call `operator new[](size_t, align_val_t)`, which will "
204 "terminate in case it fails to allocate, making it impossible for `operator new[](size_t, align_val_t, "
205 "nothrow_t)` to fulfill its contract (since it should return nullptr upon failure). Please make sure you "
206 "override "
207 "`operator new[](size_t, align_val_t, nothrow_t)` as well.");
208 # endif
210 return operator_new_aligned_impl(size, alignment);
211 # else
212 void* p = nullptr;
213 try {
214 p = ::operator new[](size, alignment);
215 } catch (...) {
217 return p;
218 # endif
221 _LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t) noexcept { std::__libcpp_aligned_free(ptr); }
223 _LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept {
224 ::operator delete(ptr, alignment);
227 _LIBCPP_WEAK void operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept {
228 ::operator delete(ptr, alignment);
231 _LIBCPP_WEAK void operator delete[](void* ptr, std::align_val_t alignment) noexcept {
232 ::operator delete(ptr, alignment);
235 _LIBCPP_WEAK void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept {
236 ::operator delete[](ptr, alignment);
239 _LIBCPP_WEAK void operator delete[](void* ptr, size_t, std::align_val_t alignment) noexcept {
240 ::operator delete[](ptr, alignment);
243 #endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
244 // ------------------ END COPY ------------------