diff options
Diffstat (limited to 'contrib/libc++/src/new.cpp')
-rw-r--r-- | contrib/libc++/src/new.cpp | 184 |
1 files changed, 159 insertions, 25 deletions
diff --git a/contrib/libc++/src/new.cpp b/contrib/libc++/src/new.cpp index f4f73d8..b1e8ee3 100644 --- a/contrib/libc++/src/new.cpp +++ b/contrib/libc++/src/new.cpp @@ -13,7 +13,8 @@ #include "new" -#if defined(__APPLE__) && !defined(LIBCXXRT) +#if defined(__APPLE__) && !defined(LIBCXXRT) && \ + !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) #include <cxxabi.h> #ifndef _LIBCPPABI_VERSION @@ -26,7 +27,8 @@ #if defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI) #include <cxxabi.h> #endif // defined(LIBCXX_BUILDING_LIBCXXABI) - #if !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__) + #if defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) || \ + (!defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)) static std::new_handler __new_handler; #endif // _LIBCPPABI_VERSION #endif @@ -37,12 +39,9 @@ // in this shared library, so that they can be overridden by programs // that define non-weak copies of the functions. -_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +_LIBCPP_WEAK void * -operator new(std::size_t size) -#if !__has_feature(cxx_noexcept) - throw(std::bad_alloc) -#endif +operator new(std::size_t size) _THROW_BAD_ALLOC { if (size == 0) size = 1; @@ -64,7 +63,7 @@ operator new(std::size_t size) return p; } -_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +_LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) _NOEXCEPT { @@ -83,17 +82,14 @@ operator new(size_t size, const std::nothrow_t&) _NOEXCEPT return p; } -_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +_LIBCPP_WEAK void* -operator new[](size_t size) -#if !__has_feature(cxx_noexcept) - throw(std::bad_alloc) -#endif +operator new[](size_t size) _THROW_BAD_ALLOC { return ::operator new(size); } -_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +_LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT { @@ -112,7 +108,7 @@ operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT return p; } -_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +_LIBCPP_WEAK void operator delete(void* ptr) _NOEXCEPT { @@ -120,41 +116,169 @@ operator delete(void* ptr) _NOEXCEPT ::free(ptr); } -_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +_LIBCPP_WEAK void operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT { ::operator delete(ptr); } -_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +_LIBCPP_WEAK void operator delete(void* ptr, size_t) _NOEXCEPT { ::operator delete(ptr); } -_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +_LIBCPP_WEAK void operator delete[] (void* ptr) _NOEXCEPT { ::operator delete(ptr); } -_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +_LIBCPP_WEAK void operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT { ::operator delete[](ptr); } -_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS +_LIBCPP_WEAK void operator delete[] (void* ptr, size_t) _NOEXCEPT { ::operator delete[](ptr); } +#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) + +_LIBCPP_WEAK +void * +operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC +{ + if (size == 0) + size = 1; + if (static_cast<size_t>(alignment) < sizeof(void*)) + alignment = std::align_val_t(sizeof(void*)); + void* p; +#if defined(_LIBCPP_MSVCRT) + while ((p = _aligned_malloc(size, static_cast<size_t>(alignment))) == nullptr) +#else + while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0) +#endif + { + // If posix_memalign fails and there is a new_handler, + // call it to try free up memory. + std::new_handler nh = std::get_new_handler(); + if (nh) + nh(); + else { +#ifndef _LIBCPP_NO_EXCEPTIONS + throw std::bad_alloc(); +#else + p = nullptr; // posix_memalign doesn't initialize 'p' on failure + break; +#endif + } + } + return p; +} + +_LIBCPP_WEAK +void* +operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT +{ + void* p = 0; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + p = ::operator new(size, alignment); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCPP_NO_EXCEPTIONS + return p; +} + +_LIBCPP_WEAK +void* +operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC +{ + return ::operator new(size, alignment); +} + +_LIBCPP_WEAK +void* +operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT +{ + void* p = 0; +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + p = ::operator new[](size, alignment); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCPP_NO_EXCEPTIONS + return p; +} + +_LIBCPP_WEAK +void +operator delete(void* ptr, std::align_val_t) _NOEXCEPT +{ + if (ptr) +#if defined(_LIBCPP_MSVCRT) + ::_aligned_free(ptr); +#else + ::free(ptr); +#endif +} + +_LIBCPP_WEAK +void +operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT +{ + ::operator delete(ptr, alignment); +} + +_LIBCPP_WEAK +void +operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT +{ + ::operator delete(ptr, alignment); +} + +_LIBCPP_WEAK +void +operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT +{ + ::operator delete(ptr, alignment); +} + +_LIBCPP_WEAK +void +operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT +{ + ::operator delete[](ptr, alignment); +} + +_LIBCPP_WEAK +void +operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT +{ + ::operator delete[](ptr, alignment); +} + +#endif // !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) + #endif // !__GLIBCXX__ namespace std @@ -206,6 +330,8 @@ bad_array_new_length::bad_array_new_length() _NOEXCEPT { } +#ifndef __GLIBCXX__ + bad_array_new_length::~bad_array_new_length() _NOEXCEPT { } @@ -216,22 +342,28 @@ bad_array_new_length::what() const _NOEXCEPT return "bad_array_new_length"; } +#endif // !__GLIBCXX__ + #endif //LIBCXXRT -const char* -bad_array_length::what() const _NOEXCEPT +bad_array_length::bad_array_length() _NOEXCEPT { - return "bad_array_length"; } -bad_array_length::bad_array_length() _NOEXCEPT +#ifndef __GLIBCXX__ + +bad_array_length::~bad_array_length() _NOEXCEPT { } -bad_array_length::~bad_array_length() _NOEXCEPT +const char* +bad_array_length::what() const _NOEXCEPT { + return "bad_array_length"; } +#endif // !__GLIBCXX__ + #endif // _LIBCPPABI_VERSION #ifndef LIBSTDCXX @@ -241,6 +373,8 @@ __throw_bad_alloc() { #ifndef _LIBCPP_NO_EXCEPTIONS throw bad_alloc(); +#else + _VSTD::abort(); #endif } |