1 | // -*- C++ -*- |
2 | //===----------------------------- new ------------------------------------===// |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #ifndef _LIBCPP_NEW |
11 | #define _LIBCPP_NEW |
12 | |
13 | /* |
14 | new synopsis |
15 | |
16 | namespace std |
17 | { |
18 | |
19 | class bad_alloc |
20 | : public exception |
21 | { |
22 | public: |
23 | bad_alloc() noexcept; |
24 | bad_alloc(const bad_alloc&) noexcept; |
25 | bad_alloc& operator=(const bad_alloc&) noexcept; |
26 | virtual const char* what() const noexcept; |
27 | }; |
28 | |
29 | class bad_array_new_length : public bad_alloc // C++14 |
30 | { |
31 | public: |
32 | bad_array_new_length() noexcept; |
33 | }; |
34 | |
35 | enum class align_val_t : size_t {}; // C++17 |
36 | |
37 | struct destroying_delete_t { // C++20 |
38 | explicit destroying_delete_t() = default; |
39 | }; |
40 | inline constexpr destroying_delete_t destroying_delete{}; // C++20 |
41 | |
42 | struct nothrow_t { explicit nothrow_t() = default; }; |
43 | extern const nothrow_t nothrow; |
44 | typedef void (*new_handler)(); |
45 | new_handler set_new_handler(new_handler new_p) noexcept; |
46 | new_handler get_new_handler() noexcept; |
47 | |
48 | // 21.6.4, pointer optimization barrier |
49 | template <class T> constexpr T* launder(T* p) noexcept; // C++17 |
50 | } // std |
51 | |
52 | void* operator new(std::size_t size); // replaceable, nodiscard in C++2a |
53 | void* operator new(std::size_t size, std::align_val_t alignment); // replaceable, C++17, nodiscard in C++2a |
54 | void* operator new(std::size_t size, const std::nothrow_t&) noexcept; // replaceable, nodiscard in C++2a |
55 | void* operator new(std::size_t size, std::align_val_t alignment, |
56 | const std::nothrow_t&) noexcept; // replaceable, C++17, nodiscard in C++2a |
57 | void operator delete(void* ptr) noexcept; // replaceable |
58 | void operator delete(void* ptr, std::size_t size) noexcept; // replaceable, C++14 |
59 | void operator delete(void* ptr, std::align_val_t alignment) noexcept; // replaceable, C++17 |
60 | void operator delete(void* ptr, std::size_t size, |
61 | std::align_val_t alignment) noexcept; // replaceable, C++17 |
62 | void operator delete(void* ptr, const std::nothrow_t&) noexcept; // replaceable |
63 | void operator delete(void* ptr, std:align_val_t alignment, |
64 | const std::nothrow_t&) noexcept; // replaceable, C++17 |
65 | |
66 | void* operator new[](std::size_t size); // replaceable, nodiscard in C++2a |
67 | void* operator new[](std::size_t size, |
68 | std::align_val_t alignment) noexcept; // replaceable, C++17, nodiscard in C++2a |
69 | void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable, nodiscard in C++2a |
70 | void* operator new[](std::size_t size, std::align_val_t alignment, |
71 | const std::nothrow_t&) noexcept; // replaceable, C++17, nodiscard in C++2a |
72 | void operator delete[](void* ptr) noexcept; // replaceable |
73 | void operator delete[](void* ptr, std::size_t size) noexcept; // replaceable, C++14 |
74 | void operator delete[](void* ptr, |
75 | std::align_val_t alignment) noexcept; // replaceable, C++17 |
76 | void operator delete[](void* ptr, std::size_t size, |
77 | std::align_val_t alignment) noexcept; // replaceable, C++17 |
78 | void operator delete[](void* ptr, const std::nothrow_t&) noexcept; // replaceable |
79 | void operator delete[](void* ptr, std::align_val_t alignment, |
80 | const std::nothrow_t&) noexcept; // replaceable, C++17 |
81 | |
82 | void* operator new (std::size_t size, void* ptr) noexcept; // nodiscard in C++2a |
83 | void* operator new[](std::size_t size, void* ptr) noexcept; // nodiscard in C++2a |
84 | void operator delete (void* ptr, void*) noexcept; |
85 | void operator delete[](void* ptr, void*) noexcept; |
86 | |
87 | */ |
88 | |
89 | #include <__config> |
90 | #include <exception> |
91 | #include <type_traits> |
92 | #include <cstddef> |
93 | #include <version> |
94 | #ifdef _LIBCPP_NO_EXCEPTIONS |
95 | #include <cstdlib> |
96 | #endif |
97 | |
98 | #if defined(_LIBCPP_ABI_VCRUNTIME) |
99 | #include <new.h> |
100 | #endif |
101 | |
102 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
103 | #pragma GCC system_header |
104 | #endif |
105 | |
106 | #if !defined(__cpp_sized_deallocation) || __cpp_sized_deallocation < 201309L |
107 | #define _LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION |
108 | #endif |
109 | |
110 | #if !defined(_LIBCPP_BUILDING_LIBRARY) && _LIBCPP_STD_VER < 14 && \ |
111 | defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION) |
112 | # define _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION |
113 | #endif |
114 | |
115 | #if defined(_LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION) || \ |
116 | defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION) |
117 | # define _LIBCPP_HAS_NO_SIZED_DEALLOCATION |
118 | #endif |
119 | |
120 | #if !__has_builtin(__builtin_operator_new) || \ |
121 | __has_builtin(__builtin_operator_new) < 201802L |
122 | #define _LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE |
123 | #endif |
124 | |
125 | namespace std // purposefully not using versioning namespace |
126 | { |
127 | |
128 | #if !defined(_LIBCPP_ABI_VCRUNTIME) |
129 | struct _LIBCPP_TYPE_VIS nothrow_t { explicit nothrow_t() = default; }; |
130 | extern _LIBCPP_FUNC_VIS const nothrow_t nothrow; |
131 | |
132 | class _LIBCPP_EXCEPTION_ABI bad_alloc |
133 | : public exception |
134 | { |
135 | public: |
136 | bad_alloc() _NOEXCEPT; |
137 | virtual ~bad_alloc() _NOEXCEPT; |
138 | virtual const char* what() const _NOEXCEPT; |
139 | }; |
140 | |
141 | class _LIBCPP_EXCEPTION_ABI bad_array_new_length |
142 | : public bad_alloc |
143 | { |
144 | public: |
145 | bad_array_new_length() _NOEXCEPT; |
146 | virtual ~bad_array_new_length() _NOEXCEPT; |
147 | virtual const char* what() const _NOEXCEPT; |
148 | }; |
149 | |
150 | typedef void (*new_handler)(); |
151 | _LIBCPP_FUNC_VIS new_handler set_new_handler(new_handler) _NOEXCEPT; |
152 | _LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT; |
153 | |
154 | #endif // !_LIBCPP_ABI_VCRUNTIME |
155 | |
156 | _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc(); // not in C++ spec |
157 | |
158 | #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) && \ |
159 | !defined(_LIBCPP_ABI_VCRUNTIME) |
160 | #ifndef _LIBCPP_CXX03_LANG |
161 | enum class _LIBCPP_ENUM_VIS align_val_t : size_t { }; |
162 | #else |
163 | enum align_val_t { __zero = 0, __max = (size_t)-1 }; |
164 | #endif |
165 | #endif |
166 | |
167 | #if _LIBCPP_STD_VER > 17 |
168 | // Enable the declaration even if the compiler doesn't support the language |
169 | // feature. |
170 | struct destroying_delete_t { |
171 | explicit destroying_delete_t() = default; |
172 | }; |
173 | _LIBCPP_INLINE_VAR constexpr destroying_delete_t destroying_delete{}; |
174 | #endif // _LIBCPP_STD_VER > 17 |
175 | |
176 | } // std |
177 | |
178 | #if defined(_LIBCPP_CXX03_LANG) |
179 | #define _THROW_BAD_ALLOC throw(std::bad_alloc) |
180 | #else |
181 | #define _THROW_BAD_ALLOC |
182 | #endif |
183 | |
184 | #if !defined(_LIBCPP_ABI_VCRUNTIME) |
185 | |
186 | _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz) _THROW_BAD_ALLOC; |
187 | _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _LIBCPP_NOALIAS; |
188 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p) _NOEXCEPT; |
189 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT; |
190 | #ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION |
191 | _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz) _NOEXCEPT; |
192 | #endif |
193 | |
194 | _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz) _THROW_BAD_ALLOC; |
195 | _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _LIBCPP_NOALIAS; |
196 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p) _NOEXCEPT; |
197 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT; |
198 | #ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION |
199 | _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete[](void* __p, std::size_t __sz) _NOEXCEPT; |
200 | #endif |
201 | |
202 | #ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION |
203 | _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC; |
204 | _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _LIBCPP_NOALIAS; |
205 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t) _NOEXCEPT; |
206 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT; |
207 | #ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION |
208 | _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT; |
209 | #endif |
210 | |
211 | _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC; |
212 | _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _LIBCPP_NOALIAS; |
213 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t) _NOEXCEPT; |
214 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT; |
215 | #ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION |
216 | _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT; |
217 | #endif |
218 | #endif |
219 | |
220 | _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY void* operator new (std::size_t, void* __p) _NOEXCEPT {return __p;} |
221 | _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY void* operator new[](std::size_t, void* __p) _NOEXCEPT {return __p;} |
222 | inline _LIBCPP_INLINE_VISIBILITY void operator delete (void*, void*) _NOEXCEPT {} |
223 | inline _LIBCPP_INLINE_VISIBILITY void operator delete[](void*, void*) _NOEXCEPT {} |
224 | |
225 | #endif // !_LIBCPP_ABI_VCRUNTIME |
226 | |
227 | _LIBCPP_BEGIN_NAMESPACE_STD |
228 | |
229 | _LIBCPP_CONSTEXPR inline _LIBCPP_INLINE_VISIBILITY bool __is_overaligned_for_new(size_t __align) _NOEXCEPT { |
230 | #ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__ |
231 | return __align > __STDCPP_DEFAULT_NEW_ALIGNMENT__; |
232 | #else |
233 | return __align > alignment_of<max_align_t>::value; |
234 | #endif |
235 | } |
236 | |
237 | inline _LIBCPP_INLINE_VISIBILITY void *__libcpp_allocate(size_t __size, size_t __align) { |
238 | #ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION |
239 | if (__is_overaligned_for_new(__align)) { |
240 | const align_val_t __align_val = static_cast<align_val_t>(__align); |
241 | # ifdef _LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE |
242 | return ::operator new(__size, __align_val); |
243 | # else |
244 | return __builtin_operator_new(__size, __align_val); |
245 | # endif |
246 | } |
247 | #else |
248 | ((void)__align); |
249 | #endif |
250 | #ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE |
251 | return ::operator new(__size); |
252 | #else |
253 | return __builtin_operator_new(__size); |
254 | #endif |
255 | } |
256 | |
257 | struct _DeallocateCaller { |
258 | static inline _LIBCPP_INLINE_VISIBILITY |
259 | void __do_deallocate_handle_size_align(void *__ptr, size_t __size, size_t __align) { |
260 | #if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) |
261 | ((void)__align); |
262 | return __do_deallocate_handle_size(__ptr, __size); |
263 | #else |
264 | if (__is_overaligned_for_new(__align)) { |
265 | const align_val_t __align_val = static_cast<align_val_t>(__align); |
266 | return __do_deallocate_handle_size(__ptr, __size, __align_val); |
267 | } else { |
268 | return __do_deallocate_handle_size(__ptr, __size); |
269 | } |
270 | #endif |
271 | } |
272 | |
273 | static inline _LIBCPP_INLINE_VISIBILITY |
274 | void __do_deallocate_handle_align(void *__ptr, size_t __align) { |
275 | #if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) |
276 | ((void)__align); |
277 | return __do_call(__ptr); |
278 | #else |
279 | if (__is_overaligned_for_new(__align)) { |
280 | const align_val_t __align_val = static_cast<align_val_t>(__align); |
281 | return __do_call(__ptr, __align_val); |
282 | } else { |
283 | return __do_call(__ptr); |
284 | } |
285 | #endif |
286 | } |
287 | |
288 | private: |
289 | static inline void __do_deallocate_handle_size(void *__ptr, size_t __size) { |
290 | #ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION |
291 | ((void)__size); |
292 | return __do_call(__ptr); |
293 | #else |
294 | return __do_call(__ptr, __size); |
295 | #endif |
296 | } |
297 | |
298 | #ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION |
299 | static inline void __do_deallocate_handle_size(void *__ptr, size_t __size, align_val_t __align) { |
300 | #ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION |
301 | ((void)__size); |
302 | return __do_call(__ptr, __align); |
303 | #else |
304 | return __do_call(__ptr, __size, __align); |
305 | #endif |
306 | } |
307 | #endif |
308 | |
309 | private: |
310 | template <class _A1, class _A2> |
311 | static inline void __do_call(void *__ptr, _A1 __a1, _A2 __a2) { |
312 | #if defined(_LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE) || \ |
313 | defined(_LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE) |
314 | return ::operator delete(__ptr, __a1, __a2); |
315 | #else |
316 | return __builtin_operator_delete(__ptr, __a1, __a2); |
317 | #endif |
318 | } |
319 | |
320 | template <class _A1> |
321 | static inline void __do_call(void *__ptr, _A1 __a1) { |
322 | #if defined(_LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE) || \ |
323 | defined(_LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE) |
324 | return ::operator delete(__ptr, __a1); |
325 | #else |
326 | return __builtin_operator_delete(__ptr, __a1); |
327 | #endif |
328 | } |
329 | |
330 | static inline void __do_call(void *__ptr) { |
331 | #ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE |
332 | return ::operator delete(__ptr); |
333 | #else |
334 | return __builtin_operator_delete(__ptr); |
335 | #endif |
336 | } |
337 | }; |
338 | |
339 | inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate(void* __ptr, size_t __size, size_t __align) { |
340 | _DeallocateCaller::__do_deallocate_handle_size_align(__ptr, __size, __align); |
341 | } |
342 | |
343 | inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, size_t __align) { |
344 | _DeallocateCaller::__do_deallocate_handle_align(__ptr, __align); |
345 | } |
346 | |
347 | template <class _Tp> |
348 | _LIBCPP_NODISCARD_AFTER_CXX17 inline |
349 | _LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT |
350 | { |
351 | static_assert (!(is_function<_Tp>::value), "can't launder functions" ); |
352 | static_assert (!(is_same<void, typename remove_cv<_Tp>::type>::value), "can't launder cv-void" ); |
353 | #ifdef _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER |
354 | return __builtin_launder(__p); |
355 | #else |
356 | return __p; |
357 | #endif |
358 | } |
359 | |
360 | |
361 | #if _LIBCPP_STD_VER > 14 |
362 | template <class _Tp> |
363 | _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY |
364 | constexpr _Tp* launder(_Tp* __p) noexcept |
365 | { |
366 | return _VSTD::__launder(__p); |
367 | } |
368 | #endif |
369 | |
370 | _LIBCPP_END_NAMESPACE_STD |
371 | |
372 | #endif // _LIBCPP_NEW |
373 | |