xref: /openbsd-src/gnu/llvm/libcxxabi/src/stdlib_new_delete.cpp (revision 8f1d572453a8bab44a2fe956e25efc4124e87e82)
1*8f1d5724Srobert //===----------------------------------------------------------------------===//
279c2e3e6Spatrick //
379c2e3e6Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
479c2e3e6Spatrick // See https://llvm.org/LICENSE.txt for license information.
579c2e3e6Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
679c2e3e6Spatrick //
779c2e3e6Spatrick //
879c2e3e6Spatrick // This file implements the new and delete operators.
979c2e3e6Spatrick //===----------------------------------------------------------------------===//
1079c2e3e6Spatrick 
1179c2e3e6Spatrick #include "__cxxabi_config.h"
1279c2e3e6Spatrick #include <new>
1379c2e3e6Spatrick #include <cstdlib>
1479c2e3e6Spatrick 
154e0cc08cSpatrick #if !defined(_THROW_BAD_ALLOC) || !defined(_LIBCXXABI_WEAK)
164e0cc08cSpatrick #error The _THROW_BAD_ALLOC and _LIBCXXABI_WEAK libc++ macros must \
1779c2e3e6Spatrick        already be defined by libc++.
1879c2e3e6Spatrick #endif
1979c2e3e6Spatrick // Implement all new and delete operators as weak definitions
2079c2e3e6Spatrick // in this shared library, so that they can be overridden by programs
2179c2e3e6Spatrick // that define non-weak copies of the functions.
2279c2e3e6Spatrick 
2379c2e3e6Spatrick _LIBCXXABI_WEAK
2479c2e3e6Spatrick void *
operator new(std::size_t size)2579c2e3e6Spatrick operator new(std::size_t size) _THROW_BAD_ALLOC
2679c2e3e6Spatrick {
2779c2e3e6Spatrick     if (size == 0)
2879c2e3e6Spatrick         size = 1;
2979c2e3e6Spatrick     void* p;
304e0cc08cSpatrick     while ((p = ::malloc(size)) == nullptr)
3179c2e3e6Spatrick     {
3279c2e3e6Spatrick         // If malloc fails and there is a new_handler,
3379c2e3e6Spatrick         // call it to try free up memory.
3479c2e3e6Spatrick         std::new_handler nh = std::get_new_handler();
3579c2e3e6Spatrick         if (nh)
3679c2e3e6Spatrick             nh();
3779c2e3e6Spatrick         else
3879c2e3e6Spatrick #ifndef _LIBCXXABI_NO_EXCEPTIONS
3979c2e3e6Spatrick             throw std::bad_alloc();
4079c2e3e6Spatrick #else
4179c2e3e6Spatrick             break;
4279c2e3e6Spatrick #endif
4379c2e3e6Spatrick     }
4479c2e3e6Spatrick     return p;
4579c2e3e6Spatrick }
4679c2e3e6Spatrick 
4779c2e3e6Spatrick _LIBCXXABI_WEAK
4879c2e3e6Spatrick void*
operator new(size_t size,const std::nothrow_t &)494e0cc08cSpatrick operator new(size_t size, const std::nothrow_t&) noexcept
5079c2e3e6Spatrick {
514e0cc08cSpatrick     void* p = nullptr;
5279c2e3e6Spatrick #ifndef _LIBCXXABI_NO_EXCEPTIONS
5379c2e3e6Spatrick     try
5479c2e3e6Spatrick     {
5579c2e3e6Spatrick #endif // _LIBCXXABI_NO_EXCEPTIONS
5679c2e3e6Spatrick         p = ::operator new(size);
5779c2e3e6Spatrick #ifndef _LIBCXXABI_NO_EXCEPTIONS
5879c2e3e6Spatrick     }
5979c2e3e6Spatrick     catch (...)
6079c2e3e6Spatrick     {
6179c2e3e6Spatrick     }
6279c2e3e6Spatrick #endif // _LIBCXXABI_NO_EXCEPTIONS
6379c2e3e6Spatrick     return p;
6479c2e3e6Spatrick }
6579c2e3e6Spatrick 
6679c2e3e6Spatrick _LIBCXXABI_WEAK
6779c2e3e6Spatrick void*
operator new[](size_t size)6879c2e3e6Spatrick operator new[](size_t size) _THROW_BAD_ALLOC
6979c2e3e6Spatrick {
7079c2e3e6Spatrick     return ::operator new(size);
7179c2e3e6Spatrick }
7279c2e3e6Spatrick 
7379c2e3e6Spatrick _LIBCXXABI_WEAK
7479c2e3e6Spatrick void*
operator new[](size_t size,const std::nothrow_t &)754e0cc08cSpatrick operator new[](size_t size, const std::nothrow_t&) noexcept
7679c2e3e6Spatrick {
774e0cc08cSpatrick     void* p = nullptr;
7879c2e3e6Spatrick #ifndef _LIBCXXABI_NO_EXCEPTIONS
7979c2e3e6Spatrick     try
8079c2e3e6Spatrick     {
8179c2e3e6Spatrick #endif // _LIBCXXABI_NO_EXCEPTIONS
8279c2e3e6Spatrick         p = ::operator new[](size);
8379c2e3e6Spatrick #ifndef _LIBCXXABI_NO_EXCEPTIONS
8479c2e3e6Spatrick     }
8579c2e3e6Spatrick     catch (...)
8679c2e3e6Spatrick     {
8779c2e3e6Spatrick     }
8879c2e3e6Spatrick #endif // _LIBCXXABI_NO_EXCEPTIONS
8979c2e3e6Spatrick     return p;
9079c2e3e6Spatrick }
9179c2e3e6Spatrick 
9279c2e3e6Spatrick _LIBCXXABI_WEAK
9379c2e3e6Spatrick void
operator delete(void * ptr)944e0cc08cSpatrick operator delete(void* ptr) noexcept
9579c2e3e6Spatrick {
9679c2e3e6Spatrick     ::free(ptr);
9779c2e3e6Spatrick }
9879c2e3e6Spatrick 
9979c2e3e6Spatrick _LIBCXXABI_WEAK
10079c2e3e6Spatrick void
operator delete(void * ptr,const std::nothrow_t &)1014e0cc08cSpatrick operator delete(void* ptr, const std::nothrow_t&) noexcept
10279c2e3e6Spatrick {
10379c2e3e6Spatrick     ::operator delete(ptr);
10479c2e3e6Spatrick }
10579c2e3e6Spatrick 
10679c2e3e6Spatrick _LIBCXXABI_WEAK
10779c2e3e6Spatrick void
operator delete(void * ptr,size_t)1084e0cc08cSpatrick operator delete(void* ptr, size_t) noexcept
10979c2e3e6Spatrick {
11079c2e3e6Spatrick     ::operator delete(ptr);
11179c2e3e6Spatrick }
11279c2e3e6Spatrick 
11379c2e3e6Spatrick _LIBCXXABI_WEAK
11479c2e3e6Spatrick void
operator delete[](void * ptr)1154e0cc08cSpatrick operator delete[] (void* ptr) noexcept
11679c2e3e6Spatrick {
11779c2e3e6Spatrick     ::operator delete(ptr);
11879c2e3e6Spatrick }
11979c2e3e6Spatrick 
12079c2e3e6Spatrick _LIBCXXABI_WEAK
12179c2e3e6Spatrick void
operator delete[](void * ptr,const std::nothrow_t &)1224e0cc08cSpatrick operator delete[] (void* ptr, const std::nothrow_t&) noexcept
12379c2e3e6Spatrick {
12479c2e3e6Spatrick     ::operator delete[](ptr);
12579c2e3e6Spatrick }
12679c2e3e6Spatrick 
12779c2e3e6Spatrick _LIBCXXABI_WEAK
12879c2e3e6Spatrick void
operator delete[](void * ptr,size_t)1294e0cc08cSpatrick operator delete[] (void* ptr, size_t) noexcept
13079c2e3e6Spatrick {
13179c2e3e6Spatrick     ::operator delete[](ptr);
13279c2e3e6Spatrick }
13379c2e3e6Spatrick 
13479c2e3e6Spatrick #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
13579c2e3e6Spatrick 
13679c2e3e6Spatrick _LIBCXXABI_WEAK
13779c2e3e6Spatrick void *
operator new(std::size_t size,std::align_val_t alignment)13879c2e3e6Spatrick operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
13979c2e3e6Spatrick {
14079c2e3e6Spatrick     if (size == 0)
14179c2e3e6Spatrick         size = 1;
14279c2e3e6Spatrick     if (static_cast<size_t>(alignment) < sizeof(void*))
14379c2e3e6Spatrick       alignment = std::align_val_t(sizeof(void*));
1444e0cc08cSpatrick 
1454e0cc08cSpatrick     // Try allocating memory. If allocation fails and there is a new_handler,
1464e0cc08cSpatrick     // call it to try free up memory, and try again until it succeeds, or until
1474e0cc08cSpatrick     // the new_handler decides to terminate.
1484e0cc08cSpatrick     //
1494e0cc08cSpatrick     // If allocation fails and there is no new_handler, we throw bad_alloc
1504e0cc08cSpatrick     // (or return nullptr if exceptions are disabled).
15179c2e3e6Spatrick     void* p;
1524e0cc08cSpatrick     while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr)
15379c2e3e6Spatrick     {
15479c2e3e6Spatrick         std::new_handler nh = std::get_new_handler();
15579c2e3e6Spatrick         if (nh)
15679c2e3e6Spatrick             nh();
15779c2e3e6Spatrick         else {
15879c2e3e6Spatrick #ifndef _LIBCXXABI_NO_EXCEPTIONS
15979c2e3e6Spatrick             throw std::bad_alloc();
16079c2e3e6Spatrick #else
16179c2e3e6Spatrick             break;
16279c2e3e6Spatrick #endif
16379c2e3e6Spatrick         }
16479c2e3e6Spatrick     }
16579c2e3e6Spatrick     return p;
16679c2e3e6Spatrick }
16779c2e3e6Spatrick 
16879c2e3e6Spatrick _LIBCXXABI_WEAK
16979c2e3e6Spatrick void*
operator new(size_t size,std::align_val_t alignment,const std::nothrow_t &)1704e0cc08cSpatrick operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
17179c2e3e6Spatrick {
1724e0cc08cSpatrick     void* p = nullptr;
17379c2e3e6Spatrick #ifndef _LIBCXXABI_NO_EXCEPTIONS
17479c2e3e6Spatrick     try
17579c2e3e6Spatrick     {
17679c2e3e6Spatrick #endif // _LIBCXXABI_NO_EXCEPTIONS
17779c2e3e6Spatrick         p = ::operator new(size, alignment);
17879c2e3e6Spatrick #ifndef _LIBCXXABI_NO_EXCEPTIONS
17979c2e3e6Spatrick     }
18079c2e3e6Spatrick     catch (...)
18179c2e3e6Spatrick     {
18279c2e3e6Spatrick     }
18379c2e3e6Spatrick #endif // _LIBCXXABI_NO_EXCEPTIONS
18479c2e3e6Spatrick     return p;
18579c2e3e6Spatrick }
18679c2e3e6Spatrick 
18779c2e3e6Spatrick _LIBCXXABI_WEAK
18879c2e3e6Spatrick void*
operator new[](size_t size,std::align_val_t alignment)18979c2e3e6Spatrick operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
19079c2e3e6Spatrick {
19179c2e3e6Spatrick     return ::operator new(size, alignment);
19279c2e3e6Spatrick }
19379c2e3e6Spatrick 
19479c2e3e6Spatrick _LIBCXXABI_WEAK
19579c2e3e6Spatrick void*
operator new[](size_t size,std::align_val_t alignment,const std::nothrow_t &)1964e0cc08cSpatrick operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept
19779c2e3e6Spatrick {
1984e0cc08cSpatrick     void* p = nullptr;
19979c2e3e6Spatrick #ifndef _LIBCXXABI_NO_EXCEPTIONS
20079c2e3e6Spatrick     try
20179c2e3e6Spatrick     {
20279c2e3e6Spatrick #endif // _LIBCXXABI_NO_EXCEPTIONS
20379c2e3e6Spatrick         p = ::operator new[](size, alignment);
20479c2e3e6Spatrick #ifndef _LIBCXXABI_NO_EXCEPTIONS
20579c2e3e6Spatrick     }
20679c2e3e6Spatrick     catch (...)
20779c2e3e6Spatrick     {
20879c2e3e6Spatrick     }
20979c2e3e6Spatrick #endif // _LIBCXXABI_NO_EXCEPTIONS
21079c2e3e6Spatrick     return p;
21179c2e3e6Spatrick }
21279c2e3e6Spatrick 
21379c2e3e6Spatrick _LIBCXXABI_WEAK
21479c2e3e6Spatrick void
operator delete(void * ptr,std::align_val_t)2154e0cc08cSpatrick operator delete(void* ptr, std::align_val_t) noexcept
21679c2e3e6Spatrick {
2174e0cc08cSpatrick     std::__libcpp_aligned_free(ptr);
21879c2e3e6Spatrick }
21979c2e3e6Spatrick 
22079c2e3e6Spatrick _LIBCXXABI_WEAK
22179c2e3e6Spatrick void
operator delete(void * ptr,std::align_val_t alignment,const std::nothrow_t &)2224e0cc08cSpatrick operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept
22379c2e3e6Spatrick {
22479c2e3e6Spatrick     ::operator delete(ptr, alignment);
22579c2e3e6Spatrick }
22679c2e3e6Spatrick 
22779c2e3e6Spatrick _LIBCXXABI_WEAK
22879c2e3e6Spatrick void
operator delete(void * ptr,size_t,std::align_val_t alignment)2294e0cc08cSpatrick operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept
23079c2e3e6Spatrick {
23179c2e3e6Spatrick     ::operator delete(ptr, alignment);
23279c2e3e6Spatrick }
23379c2e3e6Spatrick 
23479c2e3e6Spatrick _LIBCXXABI_WEAK
23579c2e3e6Spatrick void
operator delete[](void * ptr,std::align_val_t alignment)2364e0cc08cSpatrick operator delete[] (void* ptr, std::align_val_t alignment) noexcept
23779c2e3e6Spatrick {
23879c2e3e6Spatrick     ::operator delete(ptr, alignment);
23979c2e3e6Spatrick }
24079c2e3e6Spatrick 
24179c2e3e6Spatrick _LIBCXXABI_WEAK
24279c2e3e6Spatrick void
operator delete[](void * ptr,std::align_val_t alignment,const std::nothrow_t &)2434e0cc08cSpatrick operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept
24479c2e3e6Spatrick {
24579c2e3e6Spatrick     ::operator delete[](ptr, alignment);
24679c2e3e6Spatrick }
24779c2e3e6Spatrick 
24879c2e3e6Spatrick _LIBCXXABI_WEAK
24979c2e3e6Spatrick void
operator delete[](void * ptr,size_t,std::align_val_t alignment)2504e0cc08cSpatrick operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept
25179c2e3e6Spatrick {
25279c2e3e6Spatrick     ::operator delete[](ptr, alignment);
25379c2e3e6Spatrick }
25479c2e3e6Spatrick 
25579c2e3e6Spatrick #endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
256