1349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 97a6dacacSDimitry Andric #include "include/overridable_function.h" 10*0fca6ea1SDimitry Andric #include <__assert> 1106c3fb27SDimitry Andric #include <__memory/aligned_alloc.h> 127a6dacacSDimitry Andric #include <cstddef> 1306c3fb27SDimitry Andric #include <cstdlib> 1481ad6265SDimitry Andric #include <new> 150b57cec5SDimitry Andric 1606c3fb27SDimitry Andric #if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_VCRUNTIME) 170b57cec5SDimitry Andric 1806c3fb27SDimitry Andric // The code below is copied as-is into libc++abi's libcxxabi/src/stdlib_new_delete.cpp 1906c3fb27SDimitry Andric // file. The version in this file is the canonical one. 200b57cec5SDimitry Andric 217a6dacacSDimitry Andric inline void __throw_bad_alloc_shim() { std::__throw_bad_alloc(); } 227a6dacacSDimitry Andric 237a6dacacSDimitry Andric # define _LIBCPP_ASSERT_SHIM(expr, str) _LIBCPP_ASSERT(expr, str) 247a6dacacSDimitry Andric 2506c3fb27SDimitry Andric // ------------------ BEGIN COPY ------------------ 260b57cec5SDimitry Andric // Implement all new and delete operators as weak definitions 270b57cec5SDimitry Andric // in this shared library, so that they can be overridden by programs 280b57cec5SDimitry Andric // that define non-weak copies of the functions. 290b57cec5SDimitry Andric 307a6dacacSDimitry Andric static void* operator_new_impl(std::size_t size) { 310b57cec5SDimitry Andric if (size == 0) 320b57cec5SDimitry Andric size = 1; 330b57cec5SDimitry Andric void* p; 345f757f3fSDimitry Andric while ((p = std::malloc(size)) == nullptr) { 350b57cec5SDimitry Andric // If malloc fails and there is a new_handler, 360b57cec5SDimitry Andric // call it to try free up memory. 370b57cec5SDimitry Andric std::new_handler nh = std::get_new_handler(); 380b57cec5SDimitry Andric if (nh) 390b57cec5SDimitry Andric nh(); 400b57cec5SDimitry Andric else 410b57cec5SDimitry Andric break; 420b57cec5SDimitry Andric } 430b57cec5SDimitry Andric return p; 440b57cec5SDimitry Andric } 450b57cec5SDimitry Andric 467a6dacacSDimitry Andric _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC { 475f757f3fSDimitry Andric void* p = operator_new_impl(size); 485f757f3fSDimitry Andric if (p == nullptr) 497a6dacacSDimitry Andric __throw_bad_alloc_shim(); 505f757f3fSDimitry Andric return p; 515f757f3fSDimitry Andric } 525f757f3fSDimitry Andric 535f757f3fSDimitry Andric _LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept { 547a6dacacSDimitry Andric # ifdef _LIBCPP_HAS_NO_EXCEPTIONS 557a6dacacSDimitry Andric # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 567a6dacacSDimitry Andric _LIBCPP_ASSERT_SHIM( 577a6dacacSDimitry Andric !std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new)), 587a6dacacSDimitry Andric "libc++ was configured with exceptions disabled and `operator new(size_t)` has been overridden, " 597a6dacacSDimitry Andric "but `operator new(size_t, nothrow_t)` has not been overridden. This is problematic because " 607a6dacacSDimitry Andric "`operator new(size_t, nothrow_t)` must call `operator new(size_t)`, which will terminate in case " 617a6dacacSDimitry Andric "it fails to allocate, making it impossible for `operator new(size_t, nothrow_t)` to fulfill its " 627a6dacacSDimitry Andric "contract (since it should return nullptr upon failure). Please make sure you override " 637a6dacacSDimitry Andric "`operator new(size_t, nothrow_t)` as well."); 647a6dacacSDimitry Andric # endif 657a6dacacSDimitry Andric 667a6dacacSDimitry Andric return operator_new_impl(size); 677a6dacacSDimitry Andric # else 68e8d8bef9SDimitry Andric void* p = nullptr; 695f757f3fSDimitry Andric try { 700b57cec5SDimitry Andric p = ::operator new(size); 715f757f3fSDimitry Andric } catch (...) { 720b57cec5SDimitry Andric } 730b57cec5SDimitry Andric return p; 747a6dacacSDimitry Andric # endif 750b57cec5SDimitry Andric } 760b57cec5SDimitry Andric 777a6dacacSDimitry Andric _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new[](size_t size) _THROW_BAD_ALLOC { 787a6dacacSDimitry Andric return ::operator new(size); 797a6dacacSDimitry Andric } 800b57cec5SDimitry Andric 815f757f3fSDimitry Andric _LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept { 827a6dacacSDimitry Andric # ifdef _LIBCPP_HAS_NO_EXCEPTIONS 837a6dacacSDimitry Andric # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 847a6dacacSDimitry Andric _LIBCPP_ASSERT_SHIM( 857a6dacacSDimitry Andric !std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new[])), 867a6dacacSDimitry Andric "libc++ was configured with exceptions disabled and `operator new[](size_t)` has been overridden, " 877a6dacacSDimitry Andric "but `operator new[](size_t, nothrow_t)` has not been overridden. This is problematic because " 887a6dacacSDimitry Andric "`operator new[](size_t, nothrow_t)` must call `operator new[](size_t)`, which will terminate in case " 897a6dacacSDimitry Andric "it fails to allocate, making it impossible for `operator new[](size_t, nothrow_t)` to fulfill its " 907a6dacacSDimitry Andric "contract (since it should return nullptr upon failure). Please make sure you override " 917a6dacacSDimitry Andric "`operator new[](size_t, nothrow_t)` as well."); 927a6dacacSDimitry Andric # endif 937a6dacacSDimitry Andric 947a6dacacSDimitry Andric return operator_new_impl(size); 957a6dacacSDimitry Andric # else 96e8d8bef9SDimitry Andric void* p = nullptr; 975f757f3fSDimitry Andric try { 980b57cec5SDimitry Andric p = ::operator new[](size); 995f757f3fSDimitry Andric } catch (...) { 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric return p; 1027a6dacacSDimitry Andric # endif 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric 1055f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr) noexcept { std::free(ptr); } 1060b57cec5SDimitry Andric 1075f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr, const std::nothrow_t&) noexcept { ::operator delete(ptr); } 1080b57cec5SDimitry Andric 1095f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr, size_t) noexcept { ::operator delete(ptr); } 1100b57cec5SDimitry Andric 1115f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr) noexcept { ::operator delete(ptr); } 1120b57cec5SDimitry Andric 1135f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr, const std::nothrow_t&) noexcept { ::operator delete[](ptr); } 1140b57cec5SDimitry Andric 1155f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); } 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric # if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) 1180b57cec5SDimitry Andric 1197a6dacacSDimitry Andric static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) { 1200b57cec5SDimitry Andric if (size == 0) 1210b57cec5SDimitry Andric size = 1; 1220b57cec5SDimitry Andric if (static_cast<size_t>(alignment) < sizeof(void*)) 1230b57cec5SDimitry Andric alignment = std::align_val_t(sizeof(void*)); 124e8d8bef9SDimitry Andric 125e8d8bef9SDimitry Andric // Try allocating memory. If allocation fails and there is a new_handler, 126e8d8bef9SDimitry Andric // call it to try free up memory, and try again until it succeeds, or until 127e8d8bef9SDimitry Andric // the new_handler decides to terminate. 1280b57cec5SDimitry Andric void* p; 1295f757f3fSDimitry Andric while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr) { 1300b57cec5SDimitry Andric std::new_handler nh = std::get_new_handler(); 1310b57cec5SDimitry Andric if (nh) 1320b57cec5SDimitry Andric nh(); 1335f757f3fSDimitry Andric else 1340b57cec5SDimitry Andric break; 1350b57cec5SDimitry Andric } 1360b57cec5SDimitry Andric return p; 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric 1397a6dacacSDimitry Andric _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* 1407a6dacacSDimitry Andric operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { 1415f757f3fSDimitry Andric void* p = operator_new_aligned_impl(size, alignment); 1425f757f3fSDimitry Andric if (p == nullptr) 1437a6dacacSDimitry Andric __throw_bad_alloc_shim(); 1445f757f3fSDimitry Andric return p; 1455f757f3fSDimitry Andric } 1465f757f3fSDimitry Andric 1475f757f3fSDimitry Andric _LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept { 1487a6dacacSDimitry Andric # ifdef _LIBCPP_HAS_NO_EXCEPTIONS 1497a6dacacSDimitry Andric # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1507a6dacacSDimitry Andric _LIBCPP_ASSERT_SHIM( 1517a6dacacSDimitry Andric !std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new)), 1527a6dacacSDimitry Andric "libc++ was configured with exceptions disabled and `operator new(size_t, align_val_t)` has been overridden, " 1537a6dacacSDimitry Andric "but `operator new(size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because " 1547a6dacacSDimitry Andric "`operator new(size_t, align_val_t, nothrow_t)` must call `operator new(size_t, align_val_t)`, which will " 1557a6dacacSDimitry Andric "terminate in case it fails to allocate, making it impossible for `operator new(size_t, align_val_t, nothrow_t)` " 1567a6dacacSDimitry Andric "to fulfill its contract (since it should return nullptr upon failure). Please make sure you override " 1577a6dacacSDimitry Andric "`operator new(size_t, align_val_t, nothrow_t)` as well."); 1587a6dacacSDimitry Andric # endif 1597a6dacacSDimitry Andric 1607a6dacacSDimitry Andric return operator_new_aligned_impl(size, alignment); 1617a6dacacSDimitry Andric # else 162e8d8bef9SDimitry Andric void* p = nullptr; 1635f757f3fSDimitry Andric try { 1640b57cec5SDimitry Andric p = ::operator new(size, alignment); 1655f757f3fSDimitry Andric } catch (...) { 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric return p; 1687a6dacacSDimitry Andric # endif 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric 1717a6dacacSDimitry Andric _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* 1727a6dacacSDimitry Andric operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { 1730b57cec5SDimitry Andric return ::operator new(size, alignment); 1740b57cec5SDimitry Andric } 1750b57cec5SDimitry Andric 1765f757f3fSDimitry Andric _LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept { 1777a6dacacSDimitry Andric # ifdef _LIBCPP_HAS_NO_EXCEPTIONS 1787a6dacacSDimitry Andric # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1797a6dacacSDimitry Andric _LIBCPP_ASSERT_SHIM( 1807a6dacacSDimitry Andric !std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new[])), 1817a6dacacSDimitry Andric "libc++ was configured with exceptions disabled and `operator new[](size_t, align_val_t)` has been overridden, " 1827a6dacacSDimitry Andric "but `operator new[](size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because " 1837a6dacacSDimitry Andric "`operator new[](size_t, align_val_t, nothrow_t)` must call `operator new[](size_t, align_val_t)`, which will " 1847a6dacacSDimitry Andric "terminate in case it fails to allocate, making it impossible for `operator new[](size_t, align_val_t, " 1857a6dacacSDimitry Andric "nothrow_t)` to fulfill its contract (since it should return nullptr upon failure). Please make sure you " 1867a6dacacSDimitry Andric "override " 1877a6dacacSDimitry Andric "`operator new[](size_t, align_val_t, nothrow_t)` as well."); 1887a6dacacSDimitry Andric # endif 1897a6dacacSDimitry Andric 1907a6dacacSDimitry Andric return operator_new_aligned_impl(size, alignment); 1917a6dacacSDimitry Andric # else 192e8d8bef9SDimitry Andric void* p = nullptr; 1935f757f3fSDimitry Andric try { 1940b57cec5SDimitry Andric p = ::operator new[](size, alignment); 1955f757f3fSDimitry Andric } catch (...) { 1960b57cec5SDimitry Andric } 1970b57cec5SDimitry Andric return p; 1987a6dacacSDimitry Andric # endif 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric 2015f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t) noexcept { std::__libcpp_aligned_free(ptr); } 2020b57cec5SDimitry Andric 2035f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept { 2040b57cec5SDimitry Andric ::operator delete(ptr, alignment); 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric 2075f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept { 2080b57cec5SDimitry Andric ::operator delete(ptr, alignment); 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric 2115f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr, std::align_val_t alignment) noexcept { 2120b57cec5SDimitry Andric ::operator delete(ptr, alignment); 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric 2155f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept { 2160b57cec5SDimitry Andric ::operator delete[](ptr, alignment); 2170b57cec5SDimitry Andric } 2180b57cec5SDimitry Andric 2195f757f3fSDimitry Andric _LIBCPP_WEAK void operator delete[](void* ptr, size_t, std::align_val_t alignment) noexcept { 2200b57cec5SDimitry Andric ::operator delete[](ptr, alignment); 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric # endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION 22406c3fb27SDimitry Andric // ------------------ END COPY ------------------ 22506c3fb27SDimitry Andric 22606c3fb27SDimitry Andric #endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME 227