diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-03-26 22:41:26 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-03-26 22:41:26 -0400 |
| commit | ed0dbe1a64a80dc329daab3776bda9d3fa54c9f8 (patch) | |
| tree | 3a1c15f85d11853a0a451f2b9da59f4b99346cf6 /lib/libcxxabi/src/stdlib_new_delete.cpp | |
| parent | 463b90b977ba4817f6cf90a85e8609092f53dfd2 (diff) | |
| download | zig-ed0dbe1a64a80dc329daab3776bda9d3fa54c9f8.tar.gz zig-ed0dbe1a64a80dc329daab3776bda9d3fa54c9f8.zip | |
add libc++ and libc++abi sources
upstream: LLVM 10
Diffstat (limited to 'lib/libcxxabi/src/stdlib_new_delete.cpp')
| -rw-r--r-- | lib/libcxxabi/src/stdlib_new_delete.cpp | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/lib/libcxxabi/src/stdlib_new_delete.cpp b/lib/libcxxabi/src/stdlib_new_delete.cpp new file mode 100644 index 0000000000..698c5f7c29 --- /dev/null +++ b/lib/libcxxabi/src/stdlib_new_delete.cpp @@ -0,0 +1,262 @@ +//===--------------------- stdlib_new_delete.cpp --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// +// This file implements the new and delete operators. +//===----------------------------------------------------------------------===// + +#define _LIBCPP_BUILDING_LIBRARY +#include "__cxxabi_config.h" +#include <new> +#include <cstdlib> + +#if !defined(_THROW_BAD_ALLOC) || !defined(_NOEXCEPT) || !defined(_LIBCXXABI_WEAK) +#error The _THROW_BAD_ALLOC, _NOEXCEPT, and _LIBCXXABI_WEAK libc++ macros must \ + already be defined by libc++. +#endif +// Implement all new and delete operators as weak definitions +// in this shared library, so that they can be overridden by programs +// that define non-weak copies of the functions. + +_LIBCXXABI_WEAK +void * +operator new(std::size_t size) _THROW_BAD_ALLOC +{ + if (size == 0) + size = 1; + void* p; + while ((p = ::malloc(size)) == 0) + { + // If malloc 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 _LIBCXXABI_NO_EXCEPTIONS + throw std::bad_alloc(); +#else + break; +#endif + } + return p; +} + +_LIBCXXABI_WEAK +void* +operator new(size_t size, const std::nothrow_t&) _NOEXCEPT +{ + void* p = 0; +#ifndef _LIBCXXABI_NO_EXCEPTIONS + try + { +#endif // _LIBCXXABI_NO_EXCEPTIONS + p = ::operator new(size); +#ifndef _LIBCXXABI_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCXXABI_NO_EXCEPTIONS + return p; +} + +_LIBCXXABI_WEAK +void* +operator new[](size_t size) _THROW_BAD_ALLOC +{ + return ::operator new(size); +} + +_LIBCXXABI_WEAK +void* +operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT +{ + void* p = 0; +#ifndef _LIBCXXABI_NO_EXCEPTIONS + try + { +#endif // _LIBCXXABI_NO_EXCEPTIONS + p = ::operator new[](size); +#ifndef _LIBCXXABI_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCXXABI_NO_EXCEPTIONS + return p; +} + +_LIBCXXABI_WEAK +void +operator delete(void* ptr) _NOEXCEPT +{ + if (ptr) + ::free(ptr); +} + +_LIBCXXABI_WEAK +void +operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT +{ + ::operator delete(ptr); +} + +_LIBCXXABI_WEAK +void +operator delete(void* ptr, size_t) _NOEXCEPT +{ + ::operator delete(ptr); +} + +_LIBCXXABI_WEAK +void +operator delete[] (void* ptr) _NOEXCEPT +{ + ::operator delete(ptr); +} + +_LIBCXXABI_WEAK +void +operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT +{ + ::operator delete[](ptr); +} + +_LIBCXXABI_WEAK +void +operator delete[] (void* ptr, size_t) _NOEXCEPT +{ + ::operator delete[](ptr); +} + +#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) + +_LIBCXXABI_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_WIN32API) + 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 _LIBCXXABI_NO_EXCEPTIONS + throw std::bad_alloc(); +#else + p = nullptr; // posix_memalign doesn't initialize 'p' on failure + break; +#endif + } + } + return p; +} + +_LIBCXXABI_WEAK +void* +operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT +{ + void* p = 0; +#ifndef _LIBCXXABI_NO_EXCEPTIONS + try + { +#endif // _LIBCXXABI_NO_EXCEPTIONS + p = ::operator new(size, alignment); +#ifndef _LIBCXXABI_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCXXABI_NO_EXCEPTIONS + return p; +} + +_LIBCXXABI_WEAK +void* +operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC +{ + return ::operator new(size, alignment); +} + +_LIBCXXABI_WEAK +void* +operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT +{ + void* p = 0; +#ifndef _LIBCXXABI_NO_EXCEPTIONS + try + { +#endif // _LIBCXXABI_NO_EXCEPTIONS + p = ::operator new[](size, alignment); +#ifndef _LIBCXXABI_NO_EXCEPTIONS + } + catch (...) + { + } +#endif // _LIBCXXABI_NO_EXCEPTIONS + return p; +} + +_LIBCXXABI_WEAK +void +operator delete(void* ptr, std::align_val_t) _NOEXCEPT +{ + if (ptr) +#if defined(_LIBCPP_WIN32API) + ::_aligned_free(ptr); +#else + ::free(ptr); +#endif +} + +_LIBCXXABI_WEAK +void +operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT +{ + ::operator delete(ptr, alignment); +} + +_LIBCXXABI_WEAK +void +operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT +{ + ::operator delete(ptr, alignment); +} + +_LIBCXXABI_WEAK +void +operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT +{ + ::operator delete(ptr, alignment); +} + +_LIBCXXABI_WEAK +void +operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT +{ + ::operator delete[](ptr, alignment); +} + +_LIBCXXABI_WEAK +void +operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT +{ + ::operator delete[](ptr, alignment); +} + +#endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION |
