/Users/buildslave/jenkins/workspace/coverage/llvm-project/libcxx/src/new.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #include <new> |
10 | | #include <stdlib.h> |
11 | | |
12 | | #include "include/atomic_support.h" |
13 | | |
14 | | #if defined(_LIBCPP_ABI_MICROSOFT) |
15 | | # if !defined(_LIBCPP_ABI_VCRUNTIME) |
16 | | # include "support/runtime/new_handler_fallback.ipp" |
17 | | # endif |
18 | | #elif defined(LIBCXX_BUILDING_LIBCXXABI) |
19 | | # include <cxxabi.h> |
20 | | #elif defined(LIBCXXRT) |
21 | | # include <cxxabi.h> |
22 | | # include "support/runtime/new_handler_fallback.ipp" |
23 | | #elif defined(__GLIBCXX__) |
24 | | // nothing to do |
25 | | #else |
26 | | # include "support/runtime/new_handler_fallback.ipp" |
27 | | #endif |
28 | | |
29 | | namespace std |
30 | | { |
31 | | |
32 | | #ifndef __GLIBCXX__ |
33 | | const nothrow_t nothrow{}; |
34 | | #endif |
35 | | |
36 | | #ifndef LIBSTDCXX |
37 | | |
38 | | void |
39 | | __throw_bad_alloc() |
40 | 0 | { |
41 | 0 | #ifndef _LIBCPP_NO_EXCEPTIONS |
42 | 0 | throw bad_alloc(); |
43 | | #else |
44 | | _VSTD::abort(); |
45 | | #endif |
46 | 0 | } |
47 | | |
48 | | #endif // !LIBSTDCXX |
49 | | |
50 | | } // std |
51 | | |
52 | | #if !defined(__GLIBCXX__) && \ |
53 | | !defined(_LIBCPP_ABI_VCRUNTIME) && \ |
54 | | !defined(_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS) |
55 | | |
56 | | // Implement all new and delete operators as weak definitions |
57 | | // in this shared library, so that they can be overridden by programs |
58 | | // that define non-weak copies of the functions. |
59 | | |
60 | | _LIBCPP_WEAK |
61 | | void * |
62 | | operator new(std::size_t size) _THROW_BAD_ALLOC |
63 | | { |
64 | | if (size == 0) |
65 | | size = 1; |
66 | | void* p; |
67 | | while ((p = ::malloc(size)) == nullptr) |
68 | | { |
69 | | // If malloc fails and there is a new_handler, |
70 | | // call it to try free up memory. |
71 | | std::new_handler nh = std::get_new_handler(); |
72 | | if (nh) |
73 | | nh(); |
74 | | else |
75 | | #ifndef _LIBCPP_NO_EXCEPTIONS |
76 | | throw std::bad_alloc(); |
77 | | #else |
78 | | break; |
79 | | #endif |
80 | | } |
81 | | return p; |
82 | | } |
83 | | |
84 | | _LIBCPP_WEAK |
85 | | void* |
86 | | operator new(size_t size, const std::nothrow_t&) noexcept |
87 | | { |
88 | | void* p = nullptr; |
89 | | #ifndef _LIBCPP_NO_EXCEPTIONS |
90 | | try |
91 | | { |
92 | | #endif // _LIBCPP_NO_EXCEPTIONS |
93 | | p = ::operator new(size); |
94 | | #ifndef _LIBCPP_NO_EXCEPTIONS |
95 | | } |
96 | | catch (...) |
97 | | { |
98 | | } |
99 | | #endif // _LIBCPP_NO_EXCEPTIONS |
100 | | return p; |
101 | | } |
102 | | |
103 | | _LIBCPP_WEAK |
104 | | void* |
105 | | operator new[](size_t size) _THROW_BAD_ALLOC |
106 | | { |
107 | | return ::operator new(size); |
108 | | } |
109 | | |
110 | | _LIBCPP_WEAK |
111 | | void* |
112 | | operator new[](size_t size, const std::nothrow_t&) noexcept |
113 | | { |
114 | | void* p = nullptr; |
115 | | #ifndef _LIBCPP_NO_EXCEPTIONS |
116 | | try |
117 | | { |
118 | | #endif // _LIBCPP_NO_EXCEPTIONS |
119 | | p = ::operator new[](size); |
120 | | #ifndef _LIBCPP_NO_EXCEPTIONS |
121 | | } |
122 | | catch (...) |
123 | | { |
124 | | } |
125 | | #endif // _LIBCPP_NO_EXCEPTIONS |
126 | | return p; |
127 | | } |
128 | | |
129 | | _LIBCPP_WEAK |
130 | | void |
131 | | operator delete(void* ptr) noexcept |
132 | | { |
133 | | ::free(ptr); |
134 | | } |
135 | | |
136 | | _LIBCPP_WEAK |
137 | | void |
138 | | operator delete(void* ptr, const std::nothrow_t&) noexcept |
139 | | { |
140 | | ::operator delete(ptr); |
141 | | } |
142 | | |
143 | | _LIBCPP_WEAK |
144 | | void |
145 | | operator delete(void* ptr, size_t) noexcept |
146 | | { |
147 | | ::operator delete(ptr); |
148 | | } |
149 | | |
150 | | _LIBCPP_WEAK |
151 | | void |
152 | | operator delete[] (void* ptr) noexcept |
153 | | { |
154 | | ::operator delete(ptr); |
155 | | } |
156 | | |
157 | | _LIBCPP_WEAK |
158 | | void |
159 | | operator delete[] (void* ptr, const std::nothrow_t&) noexcept |
160 | | { |
161 | | ::operator delete[](ptr); |
162 | | } |
163 | | |
164 | | _LIBCPP_WEAK |
165 | | void |
166 | | operator delete[] (void* ptr, size_t) noexcept |
167 | | { |
168 | | ::operator delete[](ptr); |
169 | | } |
170 | | |
171 | | #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) |
172 | | |
173 | | _LIBCPP_WEAK |
174 | | void * |
175 | | operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC |
176 | | { |
177 | | if (size == 0) |
178 | | size = 1; |
179 | | if (static_cast<size_t>(alignment) < sizeof(void*)) |
180 | | alignment = std::align_val_t(sizeof(void*)); |
181 | | |
182 | | // Try allocating memory. If allocation fails and there is a new_handler, |
183 | | // call it to try free up memory, and try again until it succeeds, or until |
184 | | // the new_handler decides to terminate. |
185 | | // |
186 | | // If allocation fails and there is no new_handler, we throw bad_alloc |
187 | | // (or return nullptr if exceptions are disabled). |
188 | | void* p; |
189 | | while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr) |
190 | | { |
191 | | std::new_handler nh = std::get_new_handler(); |
192 | | if (nh) |
193 | | nh(); |
194 | | else { |
195 | | #ifndef _LIBCPP_NO_EXCEPTIONS |
196 | | throw std::bad_alloc(); |
197 | | #else |
198 | | break; |
199 | | #endif |
200 | | } |
201 | | } |
202 | | return p; |
203 | | } |
204 | | |
205 | | _LIBCPP_WEAK |
206 | | void* |
207 | | operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept |
208 | | { |
209 | | void* p = nullptr; |
210 | | #ifndef _LIBCPP_NO_EXCEPTIONS |
211 | | try |
212 | | { |
213 | | #endif // _LIBCPP_NO_EXCEPTIONS |
214 | | p = ::operator new(size, alignment); |
215 | | #ifndef _LIBCPP_NO_EXCEPTIONS |
216 | | } |
217 | | catch (...) |
218 | | { |
219 | | } |
220 | | #endif // _LIBCPP_NO_EXCEPTIONS |
221 | | return p; |
222 | | } |
223 | | |
224 | | _LIBCPP_WEAK |
225 | | void* |
226 | | operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC |
227 | | { |
228 | | return ::operator new(size, alignment); |
229 | | } |
230 | | |
231 | | _LIBCPP_WEAK |
232 | | void* |
233 | | operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept |
234 | | { |
235 | | void* p = nullptr; |
236 | | #ifndef _LIBCPP_NO_EXCEPTIONS |
237 | | try |
238 | | { |
239 | | #endif // _LIBCPP_NO_EXCEPTIONS |
240 | | p = ::operator new[](size, alignment); |
241 | | #ifndef _LIBCPP_NO_EXCEPTIONS |
242 | | } |
243 | | catch (...) |
244 | | { |
245 | | } |
246 | | #endif // _LIBCPP_NO_EXCEPTIONS |
247 | | return p; |
248 | | } |
249 | | |
250 | | _LIBCPP_WEAK |
251 | | void |
252 | | operator delete(void* ptr, std::align_val_t) noexcept |
253 | | { |
254 | | std::__libcpp_aligned_free(ptr); |
255 | | } |
256 | | |
257 | | _LIBCPP_WEAK |
258 | | void |
259 | | operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept |
260 | | { |
261 | | ::operator delete(ptr, alignment); |
262 | | } |
263 | | |
264 | | _LIBCPP_WEAK |
265 | | void |
266 | | operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept |
267 | | { |
268 | | ::operator delete(ptr, alignment); |
269 | | } |
270 | | |
271 | | _LIBCPP_WEAK |
272 | | void |
273 | | operator delete[] (void* ptr, std::align_val_t alignment) noexcept |
274 | | { |
275 | | ::operator delete(ptr, alignment); |
276 | | } |
277 | | |
278 | | _LIBCPP_WEAK |
279 | | void |
280 | | operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept |
281 | | { |
282 | | ::operator delete[](ptr, alignment); |
283 | | } |
284 | | |
285 | | _LIBCPP_WEAK |
286 | | void |
287 | | operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept |
288 | | { |
289 | | ::operator delete[](ptr, alignment); |
290 | | } |
291 | | |
292 | | #endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION |
293 | | #endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME && !_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS |