1 | // -*- C++ -*- |
2 | //===----------------------------------------------------------------------===// |
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> [[nodiscard]] constexpr T* launder(T* p) noexcept; // C++17, nodiscard since C++20 |
50 | } // std |
51 | |
52 | void* operator new(std::size_t size); // replaceable, nodiscard in C++20 |
53 | void* operator new(std::size_t size, std::align_val_t alignment); // replaceable, C++17, nodiscard in C++20 |
54 | void* operator new(std::size_t size, const std::nothrow_t&) noexcept; // replaceable, nodiscard in C++20 |
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++20 |
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++20 |
67 | void* operator new[](std::size_t size, |
68 | std::align_val_t alignment) noexcept; // replaceable, C++17, nodiscard in C++20 |
69 | void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable, nodiscard in C++20 |
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++20 |
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++20 |
83 | void* operator new[](std::size_t size, void* ptr) noexcept; // nodiscard in C++20 |
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/exception.h> |
91 | #include <__type_traits/is_function.h> |
92 | #include <__type_traits/is_same.h> |
93 | #include <__type_traits/remove_cv.h> |
94 | #include <__verbose_abort> |
95 | #include <cstddef> |
96 | #include <version> |
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 && defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION) |
111 | # define _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION |
112 | #endif |
113 | |
114 | #if defined(_LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION) || defined(_LIBCPP_HAS_NO_LANGUAGE_SIZED_DEALLOCATION) |
115 | # define _LIBCPP_HAS_NO_SIZED_DEALLOCATION |
116 | #endif |
117 | |
118 | namespace std // purposefully not using versioning namespace |
119 | { |
120 | |
121 | #if !defined(_LIBCPP_ABI_VCRUNTIME) |
122 | struct _LIBCPP_EXPORTED_FROM_ABI nothrow_t { |
123 | explicit nothrow_t() = default; |
124 | }; |
125 | extern _LIBCPP_EXPORTED_FROM_ABI const nothrow_t nothrow; |
126 | |
127 | class _LIBCPP_EXPORTED_FROM_ABI bad_alloc : public exception { |
128 | public: |
129 | bad_alloc() _NOEXCEPT; |
130 | _LIBCPP_HIDE_FROM_ABI bad_alloc(const bad_alloc&) _NOEXCEPT = default; |
131 | _LIBCPP_HIDE_FROM_ABI bad_alloc& operator=(const bad_alloc&) _NOEXCEPT = default; |
132 | ~bad_alloc() _NOEXCEPT override; |
133 | const char* what() const _NOEXCEPT override; |
134 | }; |
135 | |
136 | class _LIBCPP_EXPORTED_FROM_ABI bad_array_new_length : public bad_alloc { |
137 | public: |
138 | bad_array_new_length() _NOEXCEPT; |
139 | _LIBCPP_HIDE_FROM_ABI bad_array_new_length(const bad_array_new_length&) _NOEXCEPT = default; |
140 | _LIBCPP_HIDE_FROM_ABI bad_array_new_length& operator=(const bad_array_new_length&) _NOEXCEPT = default; |
141 | ~bad_array_new_length() _NOEXCEPT override; |
142 | const char* what() const _NOEXCEPT override; |
143 | }; |
144 | |
145 | typedef void (*new_handler)(); |
146 | _LIBCPP_EXPORTED_FROM_ABI new_handler set_new_handler(new_handler) _NOEXCEPT; |
147 | _LIBCPP_EXPORTED_FROM_ABI new_handler get_new_handler() _NOEXCEPT; |
148 | |
149 | #elif defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0 // !_LIBCPP_ABI_VCRUNTIME |
150 | |
151 | // When _HAS_EXCEPTIONS == 0, these complete definitions are needed, |
152 | // since they would normally be provided in vcruntime_exception.h |
153 | class bad_alloc : public exception { |
154 | public: |
155 | bad_alloc() noexcept : exception("bad allocation" ) {} |
156 | |
157 | private: |
158 | friend class bad_array_new_length; |
159 | |
160 | bad_alloc(char const* const __message) noexcept : exception(__message) {} |
161 | }; |
162 | |
163 | class bad_array_new_length : public bad_alloc { |
164 | public: |
165 | bad_array_new_length() noexcept : bad_alloc("bad array new length" ) {} |
166 | }; |
167 | #endif // defined(_LIBCPP_ABI_VCRUNTIME) && defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0 |
168 | |
169 | _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_bad_alloc(); // not in C++ spec |
170 | |
171 | _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_array_new_length() { |
172 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS |
173 | throw bad_array_new_length(); |
174 | #else |
175 | _LIBCPP_VERBOSE_ABORT("bad_array_new_length was thrown in -fno-exceptions mode" ); |
176 | #endif |
177 | } |
178 | |
179 | #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) && !defined(_LIBCPP_ABI_VCRUNTIME) |
180 | # ifndef _LIBCPP_CXX03_LANG |
181 | enum class align_val_t : size_t {}; |
182 | # else |
183 | enum align_val_t { __zero = 0, __max = (size_t)-1 }; |
184 | # endif |
185 | #endif |
186 | |
187 | #if _LIBCPP_STD_VER >= 20 |
188 | // Enable the declaration even if the compiler doesn't support the language |
189 | // feature. |
190 | struct destroying_delete_t { |
191 | explicit destroying_delete_t() = default; |
192 | }; |
193 | inline constexpr destroying_delete_t destroying_delete{}; |
194 | #endif // _LIBCPP_STD_VER >= 20 |
195 | |
196 | } // namespace std |
197 | |
198 | #if defined(_LIBCPP_CXX03_LANG) |
199 | # define _THROW_BAD_ALLOC throw(std::bad_alloc) |
200 | #else |
201 | # define _THROW_BAD_ALLOC |
202 | #endif |
203 | |
204 | #if !defined(_LIBCPP_ABI_VCRUNTIME) |
205 | |
206 | _LIBCPP_NODISCARD _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz) _THROW_BAD_ALLOC; |
207 | _LIBCPP_NODISCARD _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT |
208 | _LIBCPP_NOALIAS; |
209 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p) _NOEXCEPT; |
210 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT; |
211 | # ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION |
212 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::size_t __sz) _NOEXCEPT; |
213 | # endif |
214 | |
215 | _LIBCPP_NODISCARD _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz) _THROW_BAD_ALLOC; |
216 | _LIBCPP_NODISCARD _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT |
217 | _LIBCPP_NOALIAS; |
218 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p) _NOEXCEPT; |
219 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT; |
220 | # ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION |
221 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::size_t __sz) _NOEXCEPT; |
222 | # endif |
223 | |
224 | # ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION |
225 | _LIBCPP_NODISCARD _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC; |
226 | _LIBCPP_NODISCARD _LIBCPP_OVERRIDABLE_FUNC_VIS void* |
227 | operator new(std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _LIBCPP_NOALIAS; |
228 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t) _NOEXCEPT; |
229 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT; |
230 | # ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION |
231 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT; |
232 | # endif |
233 | |
234 | _LIBCPP_NODISCARD _LIBCPP_OVERRIDABLE_FUNC_VIS void* |
235 | operator new[](std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC; |
236 | _LIBCPP_NODISCARD _LIBCPP_OVERRIDABLE_FUNC_VIS void* |
237 | operator new[](std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _LIBCPP_NOALIAS; |
238 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t) _NOEXCEPT; |
239 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT; |
240 | # ifndef _LIBCPP_HAS_NO_LIBRARY_SIZED_DEALLOCATION |
241 | _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT; |
242 | # endif |
243 | # endif |
244 | |
245 | _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI void* operator new(std::size_t, void* __p) _NOEXCEPT { return __p; } |
246 | _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI void* operator new[](std::size_t, void* __p) _NOEXCEPT { return __p; } |
247 | inline _LIBCPP_HIDE_FROM_ABI void operator delete(void*, void*) _NOEXCEPT {} |
248 | inline _LIBCPP_HIDE_FROM_ABI void operator delete[](void*, void*) _NOEXCEPT {} |
249 | |
250 | #endif // !_LIBCPP_ABI_VCRUNTIME |
251 | |
252 | _LIBCPP_BEGIN_NAMESPACE_STD |
253 | |
254 | _LIBCPP_CONSTEXPR inline _LIBCPP_HIDE_FROM_ABI bool __is_overaligned_for_new(size_t __align) _NOEXCEPT { |
255 | #ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__ |
256 | return __align > __STDCPP_DEFAULT_NEW_ALIGNMENT__; |
257 | #else |
258 | return __align > _LIBCPP_ALIGNOF(max_align_t); |
259 | #endif |
260 | } |
261 | |
262 | template <class... _Args> |
263 | _LIBCPP_HIDE_FROM_ABI void* __libcpp_operator_new(_Args... __args) { |
264 | #if __has_builtin(__builtin_operator_new) && __has_builtin(__builtin_operator_delete) |
265 | return __builtin_operator_new(__args...); |
266 | #else |
267 | return ::operator new(__args...); |
268 | #endif |
269 | } |
270 | |
271 | template <class... _Args> |
272 | _LIBCPP_HIDE_FROM_ABI void __libcpp_operator_delete(_Args... __args) { |
273 | #if __has_builtin(__builtin_operator_new) && __has_builtin(__builtin_operator_delete) |
274 | __builtin_operator_delete(__args...); |
275 | #else |
276 | ::operator delete(__args...); |
277 | #endif |
278 | } |
279 | |
280 | inline _LIBCPP_HIDE_FROM_ABI void* __libcpp_allocate(size_t __size, size_t __align) { |
281 | #ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION |
282 | if (__is_overaligned_for_new(__align)) { |
283 | const align_val_t __align_val = static_cast<align_val_t>(__align); |
284 | return __libcpp_operator_new(__size, __align_val); |
285 | } |
286 | #endif |
287 | |
288 | (void)__align; |
289 | return __libcpp_operator_new(__size); |
290 | } |
291 | |
292 | template <class... _Args> |
293 | _LIBCPP_HIDE_FROM_ABI void __do_deallocate_handle_size(void* __ptr, size_t __size, _Args... __args) { |
294 | #ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION |
295 | (void)__size; |
296 | return std::__libcpp_operator_delete(__ptr, __args...); |
297 | #else |
298 | return std::__libcpp_operator_delete(__ptr, __size, __args...); |
299 | #endif |
300 | } |
301 | |
302 | inline _LIBCPP_HIDE_FROM_ABI void __libcpp_deallocate(void* __ptr, size_t __size, size_t __align) { |
303 | #if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) |
304 | (void)__align; |
305 | return __do_deallocate_handle_size(__ptr, __size); |
306 | #else |
307 | if (__is_overaligned_for_new(__align)) { |
308 | const align_val_t __align_val = static_cast<align_val_t>(__align); |
309 | return __do_deallocate_handle_size(__ptr, __size, __align_val); |
310 | } else { |
311 | return __do_deallocate_handle_size(__ptr, __size); |
312 | } |
313 | #endif |
314 | } |
315 | |
316 | inline _LIBCPP_HIDE_FROM_ABI void __libcpp_deallocate_unsized(void* __ptr, size_t __align) { |
317 | #if defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) |
318 | (void)__align; |
319 | return __libcpp_operator_delete(__ptr); |
320 | #else |
321 | if (__is_overaligned_for_new(__align)) { |
322 | const align_val_t __align_val = static_cast<align_val_t>(__align); |
323 | return __libcpp_operator_delete(__ptr, __align_val); |
324 | } else { |
325 | return __libcpp_operator_delete(__ptr); |
326 | } |
327 | #endif |
328 | } |
329 | |
330 | template <class _Tp> |
331 | _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT { |
332 | static_assert(!(is_function<_Tp>::value), "can't launder functions" ); |
333 | static_assert(!(is_same<void, __remove_cv_t<_Tp> >::value), "can't launder cv-void" ); |
334 | return __builtin_launder(__p); |
335 | } |
336 | |
337 | #if _LIBCPP_STD_VER >= 17 |
338 | template <class _Tp> |
339 | [[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp* launder(_Tp* __p) noexcept { |
340 | return std::__launder(__p); |
341 | } |
342 | #endif |
343 | |
344 | #if _LIBCPP_STD_VER >= 17 |
345 | |
346 | # if defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE) |
347 | |
348 | inline constexpr size_t hardware_destructive_interference_size = __GCC_DESTRUCTIVE_SIZE; |
349 | inline constexpr size_t hardware_constructive_interference_size = __GCC_CONSTRUCTIVE_SIZE; |
350 | |
351 | # endif // defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE) |
352 | |
353 | #endif // _LIBCPP_STD_VER >= 17 |
354 | |
355 | _LIBCPP_END_NAMESPACE_STD |
356 | |
357 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
358 | # include <cstdlib> |
359 | # include <type_traits> |
360 | #endif |
361 | |
362 | #endif // _LIBCPP_NEW |
363 | |