xref: /llvm-project-15.0.7/libcxx/src/new.cpp (revision d22c9dc4)
13e519524SHoward Hinnant //===--------------------------- new.cpp ----------------------------------===//
23e519524SHoward Hinnant //
35b08a8a4SHoward Hinnant //                     The LLVM Compiler Infrastructure
43e519524SHoward Hinnant //
5412dbebeSHoward Hinnant // This file is dual licensed under the MIT and the University of Illinois Open
6412dbebeSHoward Hinnant // Source Licenses. See LICENSE.TXT for details.
73e519524SHoward Hinnant //
83e519524SHoward Hinnant //===----------------------------------------------------------------------===//
93e519524SHoward Hinnant 
106e8ebb2cSMarshall Clow #define _LIBCPP_BUILDING_NEW
116e8ebb2cSMarshall Clow 
12111e0cbeSNick Kledzik #include <stdlib.h>
13111e0cbeSNick Kledzik 
143e519524SHoward Hinnant #include "new"
153e519524SHoward Hinnant 
16*d22c9dc4SEric Fiselier #if defined(_LIBCPP_ABI_MICROSOFT)
17*d22c9dc4SEric Fiselier // nothing todo
18*d22c9dc4SEric Fiselier #elif defined(LIBCXX_BUILDING_LIBCXXABI)
19128ba719SHoward Hinnant #include <cxxabi.h>
20*d22c9dc4SEric Fiselier #elif defined(LIBCXXRT)
21*d22c9dc4SEric Fiselier #include <cxxabi.h>
22*d22c9dc4SEric Fiselier #include "support/runtime/new_handler_fallback.ipp"
23*d22c9dc4SEric Fiselier #elif defined(__GLIBCXX__)
24*d22c9dc4SEric Fiselier // nothing todo
25*d22c9dc4SEric Fiselier #else
26*d22c9dc4SEric Fiselier #include "support/runtime/new_handler_fallback.ipp"
27*d22c9dc4SEric Fiselier #endif
282c9c6a57SHoward Hinnant 
29*d22c9dc4SEric Fiselier namespace std
30*d22c9dc4SEric Fiselier {
31111e0cbeSNick Kledzik 
32926aa5f4SPeter Collingbourne #ifndef __GLIBCXX__
33*d22c9dc4SEric Fiselier const nothrow_t nothrow = {};
34*d22c9dc4SEric Fiselier #endif
35*d22c9dc4SEric Fiselier 
36*d22c9dc4SEric Fiselier #ifndef LIBSTDCXX
37*d22c9dc4SEric Fiselier 
38*d22c9dc4SEric Fiselier void
39*d22c9dc4SEric Fiselier __throw_bad_alloc()
40*d22c9dc4SEric Fiselier {
41*d22c9dc4SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
42*d22c9dc4SEric Fiselier     throw bad_alloc();
43*d22c9dc4SEric Fiselier #else
44*d22c9dc4SEric Fiselier     _VSTD::abort();
45*d22c9dc4SEric Fiselier #endif
46*d22c9dc4SEric Fiselier }
47*d22c9dc4SEric Fiselier 
48*d22c9dc4SEric Fiselier #endif // !LIBSTDCXX
49*d22c9dc4SEric Fiselier 
50*d22c9dc4SEric Fiselier }  // std
51*d22c9dc4SEric Fiselier 
52*d22c9dc4SEric Fiselier #if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_MICROSOFT)
53926aa5f4SPeter Collingbourne 
54111e0cbeSNick Kledzik // Implement all new and delete operators as weak definitions
5510fe4209SEric Fiselier // in this shared library, so that they can be overridden by programs
56111e0cbeSNick Kledzik // that define non-weak copies of the functions.
57111e0cbeSNick Kledzik 
58dce4218dSShoaib Meenai _LIBCPP_WEAK
59111e0cbeSNick Kledzik void *
600ae4f23fSEric Fiselier operator new(std::size_t size) _THROW_BAD_ALLOC
61111e0cbeSNick Kledzik {
62111e0cbeSNick Kledzik     if (size == 0)
63111e0cbeSNick Kledzik         size = 1;
64111e0cbeSNick Kledzik     void* p;
65111e0cbeSNick Kledzik     while ((p = ::malloc(size)) == 0)
66111e0cbeSNick Kledzik     {
67111e0cbeSNick Kledzik         // If malloc fails and there is a new_handler,
68111e0cbeSNick Kledzik         // call it to try free up memory.
6975357bcdSHoward Hinnant         std::new_handler nh = std::get_new_handler();
70816cb897SHoward Hinnant         if (nh)
71816cb897SHoward Hinnant             nh();
72111e0cbeSNick Kledzik         else
7354b409fdSHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS
74111e0cbeSNick Kledzik             throw std::bad_alloc();
7554b409fdSHoward Hinnant #else
7654b409fdSHoward Hinnant             break;
7754b409fdSHoward Hinnant #endif
78111e0cbeSNick Kledzik     }
79111e0cbeSNick Kledzik     return p;
80111e0cbeSNick Kledzik }
81111e0cbeSNick Kledzik 
82dce4218dSShoaib Meenai _LIBCPP_WEAK
83111e0cbeSNick Kledzik void*
8424a2ebe6SEric Fiselier operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
8524a2ebe6SEric Fiselier {
8624a2ebe6SEric Fiselier     void* p = 0;
8724a2ebe6SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
8824a2ebe6SEric Fiselier     try
8924a2ebe6SEric Fiselier     {
9024a2ebe6SEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
9124a2ebe6SEric Fiselier         p = ::operator new(size);
9224a2ebe6SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
9324a2ebe6SEric Fiselier     }
9424a2ebe6SEric Fiselier     catch (...)
9524a2ebe6SEric Fiselier     {
9624a2ebe6SEric Fiselier     }
9724a2ebe6SEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
9824a2ebe6SEric Fiselier     return p;
9924a2ebe6SEric Fiselier }
10024a2ebe6SEric Fiselier 
10124a2ebe6SEric Fiselier _LIBCPP_WEAK
10224a2ebe6SEric Fiselier void*
10324a2ebe6SEric Fiselier operator new[](size_t size) _THROW_BAD_ALLOC
10424a2ebe6SEric Fiselier {
10524a2ebe6SEric Fiselier     return ::operator new(size);
10624a2ebe6SEric Fiselier }
10724a2ebe6SEric Fiselier 
10824a2ebe6SEric Fiselier _LIBCPP_WEAK
10924a2ebe6SEric Fiselier void*
11024a2ebe6SEric Fiselier operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
11124a2ebe6SEric Fiselier {
11224a2ebe6SEric Fiselier     void* p = 0;
11324a2ebe6SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
11424a2ebe6SEric Fiselier     try
11524a2ebe6SEric Fiselier     {
11624a2ebe6SEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
11724a2ebe6SEric Fiselier         p = ::operator new[](size);
11824a2ebe6SEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
11924a2ebe6SEric Fiselier     }
12024a2ebe6SEric Fiselier     catch (...)
12124a2ebe6SEric Fiselier     {
12224a2ebe6SEric Fiselier     }
12324a2ebe6SEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
12424a2ebe6SEric Fiselier     return p;
12524a2ebe6SEric Fiselier }
12624a2ebe6SEric Fiselier 
12724a2ebe6SEric Fiselier _LIBCPP_WEAK
12824a2ebe6SEric Fiselier void
12924a2ebe6SEric Fiselier operator delete(void* ptr) _NOEXCEPT
13024a2ebe6SEric Fiselier {
13124a2ebe6SEric Fiselier     if (ptr)
13224a2ebe6SEric Fiselier         ::free(ptr);
13324a2ebe6SEric Fiselier }
13424a2ebe6SEric Fiselier 
13524a2ebe6SEric Fiselier _LIBCPP_WEAK
13624a2ebe6SEric Fiselier void
13724a2ebe6SEric Fiselier operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
13824a2ebe6SEric Fiselier {
13924a2ebe6SEric Fiselier     ::operator delete(ptr);
14024a2ebe6SEric Fiselier }
14124a2ebe6SEric Fiselier 
14224a2ebe6SEric Fiselier _LIBCPP_WEAK
14324a2ebe6SEric Fiselier void
14424a2ebe6SEric Fiselier operator delete(void* ptr, size_t) _NOEXCEPT
14524a2ebe6SEric Fiselier {
14624a2ebe6SEric Fiselier     ::operator delete(ptr);
14724a2ebe6SEric Fiselier }
14824a2ebe6SEric Fiselier 
14924a2ebe6SEric Fiselier _LIBCPP_WEAK
15024a2ebe6SEric Fiselier void
15124a2ebe6SEric Fiselier operator delete[] (void* ptr) _NOEXCEPT
15224a2ebe6SEric Fiselier {
15324a2ebe6SEric Fiselier     ::operator delete(ptr);
15424a2ebe6SEric Fiselier }
15524a2ebe6SEric Fiselier 
15624a2ebe6SEric Fiselier _LIBCPP_WEAK
15724a2ebe6SEric Fiselier void
15824a2ebe6SEric Fiselier operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT
15924a2ebe6SEric Fiselier {
16024a2ebe6SEric Fiselier     ::operator delete[](ptr);
16124a2ebe6SEric Fiselier }
16224a2ebe6SEric Fiselier 
16324a2ebe6SEric Fiselier _LIBCPP_WEAK
16424a2ebe6SEric Fiselier void
16524a2ebe6SEric Fiselier operator delete[] (void* ptr, size_t) _NOEXCEPT
16624a2ebe6SEric Fiselier {
16724a2ebe6SEric Fiselier     ::operator delete[](ptr);
16824a2ebe6SEric Fiselier }
16924a2ebe6SEric Fiselier 
170efea0451SEric Fiselier #if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
171efea0451SEric Fiselier 
17224a2ebe6SEric Fiselier _LIBCPP_WEAK
17324a2ebe6SEric Fiselier void *
1740ae4f23fSEric Fiselier operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
1750ae4f23fSEric Fiselier {
1760ae4f23fSEric Fiselier     if (size == 0)
1770ae4f23fSEric Fiselier         size = 1;
1780ae4f23fSEric Fiselier     if (static_cast<size_t>(alignment) < sizeof(void*))
1790ae4f23fSEric Fiselier       alignment = std::align_val_t(sizeof(void*));
1800ae4f23fSEric Fiselier     void* p;
181b2826a1dSSaleem Abdulrasool #if defined(_LIBCPP_MSVCRT)
1823e835372SEric Fiselier     while ((p = _aligned_malloc(size, static_cast<size_t>(alignment))) == nullptr)
1833e835372SEric Fiselier #else
1840ae4f23fSEric Fiselier     while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0)
1853e835372SEric Fiselier #endif
1860ae4f23fSEric Fiselier     {
1870ae4f23fSEric Fiselier         // If posix_memalign fails and there is a new_handler,
1880ae4f23fSEric Fiselier         // call it to try free up memory.
1890ae4f23fSEric Fiselier         std::new_handler nh = std::get_new_handler();
1900ae4f23fSEric Fiselier         if (nh)
1910ae4f23fSEric Fiselier             nh();
1920ae4f23fSEric Fiselier         else {
1930ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
1940ae4f23fSEric Fiselier             throw std::bad_alloc();
1950ae4f23fSEric Fiselier #else
1960ae4f23fSEric Fiselier             p = nullptr; // posix_memalign doesn't initialize 'p' on failure
1970ae4f23fSEric Fiselier             break;
1980ae4f23fSEric Fiselier #endif
1990ae4f23fSEric Fiselier         }
2000ae4f23fSEric Fiselier     }
2010ae4f23fSEric Fiselier     return p;
2020ae4f23fSEric Fiselier }
2030ae4f23fSEric Fiselier 
204dce4218dSShoaib Meenai _LIBCPP_WEAK
2050ae4f23fSEric Fiselier void*
2060ae4f23fSEric Fiselier operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
2070ae4f23fSEric Fiselier {
2080ae4f23fSEric Fiselier     void* p = 0;
2090ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
2100ae4f23fSEric Fiselier     try
2110ae4f23fSEric Fiselier     {
2120ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
2130ae4f23fSEric Fiselier         p = ::operator new(size, alignment);
2140ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
2150ae4f23fSEric Fiselier     }
2160ae4f23fSEric Fiselier     catch (...)
2170ae4f23fSEric Fiselier     {
2180ae4f23fSEric Fiselier     }
2190ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
2200ae4f23fSEric Fiselier     return p;
2210ae4f23fSEric Fiselier }
2220ae4f23fSEric Fiselier 
223dce4218dSShoaib Meenai _LIBCPP_WEAK
2240ae4f23fSEric Fiselier void*
2250ae4f23fSEric Fiselier operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
2260ae4f23fSEric Fiselier {
2270ae4f23fSEric Fiselier     return ::operator new(size, alignment);
2280ae4f23fSEric Fiselier }
2290ae4f23fSEric Fiselier 
230dce4218dSShoaib Meenai _LIBCPP_WEAK
2310ae4f23fSEric Fiselier void*
2320ae4f23fSEric Fiselier operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
2330ae4f23fSEric Fiselier {
2340ae4f23fSEric Fiselier     void* p = 0;
2350ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
2360ae4f23fSEric Fiselier     try
2370ae4f23fSEric Fiselier     {
2380ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
2390ae4f23fSEric Fiselier         p = ::operator new[](size, alignment);
2400ae4f23fSEric Fiselier #ifndef _LIBCPP_NO_EXCEPTIONS
2410ae4f23fSEric Fiselier     }
2420ae4f23fSEric Fiselier     catch (...)
2430ae4f23fSEric Fiselier     {
2440ae4f23fSEric Fiselier     }
2450ae4f23fSEric Fiselier #endif  // _LIBCPP_NO_EXCEPTIONS
2460ae4f23fSEric Fiselier     return p;
2470ae4f23fSEric Fiselier }
2480ae4f23fSEric Fiselier 
249dce4218dSShoaib Meenai _LIBCPP_WEAK
250111e0cbeSNick Kledzik void
2510ae4f23fSEric Fiselier operator delete(void* ptr, std::align_val_t) _NOEXCEPT
2520ae4f23fSEric Fiselier {
2530ae4f23fSEric Fiselier     if (ptr)
2547ce92f73SShoaib Meenai #if defined(_LIBCPP_MSVCRT)
2557ce92f73SShoaib Meenai         ::_aligned_free(ptr);
2567ce92f73SShoaib Meenai #else
2570ae4f23fSEric Fiselier         ::free(ptr);
2587ce92f73SShoaib Meenai #endif
2590ae4f23fSEric Fiselier }
2600ae4f23fSEric Fiselier 
261dce4218dSShoaib Meenai _LIBCPP_WEAK
2620ae4f23fSEric Fiselier void
2630ae4f23fSEric Fiselier operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
2640ae4f23fSEric Fiselier {
2650ae4f23fSEric Fiselier     ::operator delete(ptr, alignment);
2660ae4f23fSEric Fiselier }
2670ae4f23fSEric Fiselier 
268dce4218dSShoaib Meenai _LIBCPP_WEAK
2690ae4f23fSEric Fiselier void
2700ae4f23fSEric Fiselier operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
2710ae4f23fSEric Fiselier {
2720ae4f23fSEric Fiselier     ::operator delete(ptr, alignment);
2730ae4f23fSEric Fiselier }
2740ae4f23fSEric Fiselier 
275dce4218dSShoaib Meenai _LIBCPP_WEAK
2760ae4f23fSEric Fiselier void
2770ae4f23fSEric Fiselier operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT
2780ae4f23fSEric Fiselier {
2790ae4f23fSEric Fiselier     ::operator delete(ptr, alignment);
2800ae4f23fSEric Fiselier }
2810ae4f23fSEric Fiselier 
282dce4218dSShoaib Meenai _LIBCPP_WEAK
2830ae4f23fSEric Fiselier void
2840ae4f23fSEric Fiselier operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
2850ae4f23fSEric Fiselier {
2860ae4f23fSEric Fiselier     ::operator delete[](ptr, alignment);
2870ae4f23fSEric Fiselier }
2880ae4f23fSEric Fiselier 
289dce4218dSShoaib Meenai _LIBCPP_WEAK
2900ae4f23fSEric Fiselier void
2910ae4f23fSEric Fiselier operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
2920ae4f23fSEric Fiselier {
2930ae4f23fSEric Fiselier     ::operator delete[](ptr, alignment);
2940ae4f23fSEric Fiselier }
2950ae4f23fSEric Fiselier 
296*d22c9dc4SEric Fiselier #endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION
297*d22c9dc4SEric Fiselier #endif // !__GLIBCXX__ && !_LIBCPP_ABI_MICROSOFT
298