1 //===----------------------------------------------------------------------===//
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
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>
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++
24 # error The _LIBCPP_WEAK macro should be already defined by libc++
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
31 inline void __throw_bad_alloc_shim() {
32 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
33 throw std::bad_alloc();
35 abort_message("bad_alloc was thrown in -fno-exceptions mode");
39 #define _LIBCPP_ASSERT_SHIM(expr, str) \
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
) {
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();
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
);
69 __throw_bad_alloc_shim();
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
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.");
86 return operator_new_impl(size
);
90 p
= ::operator new(size
);
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
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.");
114 return operator_new_impl(size
);
118 p
= ::operator new[](size
);
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
) {
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.
149 while ((p
= std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment
), size
)) == nullptr) {
150 std::new_handler nh
= std::get_new_handler();
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
);
163 __throw_bad_alloc_shim();
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
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.");
180 return operator_new_aligned_impl(size
, alignment
);
184 p
= ::operator new(size
, alignment
);
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
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 "
207 "`operator new[](size_t, align_val_t, nothrow_t)` as well.");
210 return operator_new_aligned_impl(size
, alignment
);
214 p
= ::operator new[](size
, alignment
);
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 ------------------