Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxxabi / src / stdlib_new_delete.cpp
blob6c9990f063dde66a00db30c92aaf4c92a86ed3b9
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 <__memory/aligned_alloc.h>
11 #include <cstdlib>
12 #include <new>
14 // Perform a few sanity checks on libc++ and libc++abi macros to ensure that
15 // the code below can be an exact copy of the code in libcxx/src/new.cpp.
16 #if !defined(_THROW_BAD_ALLOC)
17 # error The _THROW_BAD_ALLOC macro should be already defined by libc++
18 #endif
20 #ifndef _LIBCPP_WEAK
21 # error The _LIBCPP_WEAK macro should be already defined by libc++
22 #endif
24 #if defined(_LIBCXXABI_NO_EXCEPTIONS) != defined(_LIBCPP_HAS_NO_EXCEPTIONS)
25 # error libc++ and libc++abi seem to disagree on whether exceptions are enabled
26 #endif
28 // ------------------ BEGIN COPY ------------------
29 // Implement all new and delete operators as weak definitions
30 // in this shared library, so that they can be overridden by programs
31 // that define non-weak copies of the functions.
33 static void* operator_new_impl(std::size_t size) noexcept {
34 if (size == 0)
35 size = 1;
36 void* p;
37 while ((p = std::malloc(size)) == nullptr) {
38 // If malloc fails and there is a new_handler,
39 // call it to try free up memory.
40 std::new_handler nh = std::get_new_handler();
41 if (nh)
42 nh();
43 else
44 break;
46 return p;
49 _LIBCPP_WEAK
50 void* operator new(std::size_t size) _THROW_BAD_ALLOC {
51 void* p = operator_new_impl(size);
52 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
53 if (p == nullptr)
54 throw std::bad_alloc();
55 #endif
56 return p;
59 _LIBCPP_WEAK
60 void* operator new(size_t size, const std::nothrow_t&) noexcept {
61 void* p = nullptr;
62 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
63 try {
64 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
65 p = ::operator new(size);
66 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
67 } catch (...) {
69 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
70 return p;
73 _LIBCPP_WEAK
74 void* operator new[](size_t size) _THROW_BAD_ALLOC { return ::operator new(size); }
76 _LIBCPP_WEAK
77 void* operator new[](size_t size, const std::nothrow_t&) noexcept {
78 void* p = nullptr;
79 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
80 try {
81 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
82 p = ::operator new[](size);
83 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
84 } catch (...) {
86 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
87 return p;
90 _LIBCPP_WEAK
91 void operator delete(void* ptr) noexcept { std::free(ptr); }
93 _LIBCPP_WEAK
94 void operator delete(void* ptr, const std::nothrow_t&) noexcept { ::operator delete(ptr); }
96 _LIBCPP_WEAK
97 void operator delete(void* ptr, size_t) noexcept { ::operator delete(ptr); }
99 _LIBCPP_WEAK
100 void operator delete[](void* ptr) noexcept { ::operator delete(ptr); }
102 _LIBCPP_WEAK
103 void operator delete[](void* ptr, const std::nothrow_t&) noexcept { ::operator delete[](ptr); }
105 _LIBCPP_WEAK
106 void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); }
108 #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
110 static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) noexcept {
111 if (size == 0)
112 size = 1;
113 if (static_cast<size_t>(alignment) < sizeof(void*))
114 alignment = std::align_val_t(sizeof(void*));
116 // Try allocating memory. If allocation fails and there is a new_handler,
117 // call it to try free up memory, and try again until it succeeds, or until
118 // the new_handler decides to terminate.
119 void* p;
120 while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr) {
121 std::new_handler nh = std::get_new_handler();
122 if (nh)
123 nh();
124 else
125 break;
127 return p;
130 _LIBCPP_WEAK
131 void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
132 void* p = operator_new_aligned_impl(size, alignment);
133 # ifndef _LIBCPP_HAS_NO_EXCEPTIONS
134 if (p == nullptr)
135 throw std::bad_alloc();
136 # endif
137 return p;
140 _LIBCPP_WEAK
141 void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
142 void* p = nullptr;
143 # ifndef _LIBCPP_HAS_NO_EXCEPTIONS
144 try {
145 # endif // _LIBCPP_HAS_NO_EXCEPTIONS
146 p = ::operator new(size, alignment);
147 # ifndef _LIBCPP_HAS_NO_EXCEPTIONS
148 } catch (...) {
150 # endif // _LIBCPP_HAS_NO_EXCEPTIONS
151 return p;
154 _LIBCPP_WEAK
155 void* operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
156 return ::operator new(size, alignment);
159 _LIBCPP_WEAK
160 void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
161 void* p = nullptr;
162 # ifndef _LIBCPP_HAS_NO_EXCEPTIONS
163 try {
164 # endif // _LIBCPP_HAS_NO_EXCEPTIONS
165 p = ::operator new[](size, alignment);
166 # ifndef _LIBCPP_HAS_NO_EXCEPTIONS
167 } catch (...) {
169 # endif // _LIBCPP_HAS_NO_EXCEPTIONS
170 return p;
173 _LIBCPP_WEAK
174 void operator delete(void* ptr, std::align_val_t) noexcept { std::__libcpp_aligned_free(ptr); }
176 _LIBCPP_WEAK
177 void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept {
178 ::operator delete(ptr, alignment);
181 _LIBCPP_WEAK
182 void operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept { ::operator delete(ptr, alignment); }
184 _LIBCPP_WEAK
185 void operator delete[](void* ptr, std::align_val_t alignment) noexcept { ::operator delete(ptr, alignment); }
187 _LIBCPP_WEAK
188 void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept {
189 ::operator delete[](ptr, alignment);
192 _LIBCPP_WEAK
193 void operator delete[](void* ptr, size_t, std::align_val_t alignment) noexcept { ::operator delete[](ptr, alignment); }
195 #endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
196 // ------------------ END COPY ------------------