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