diff options
author | Eric Fiselier <eric@efcs.ca> | 2017-03-01 23:59:34 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2017-03-01 23:59:34 +0000 |
commit | 378122744886d5d6450839b30c7f4aadf4823a25 (patch) | |
tree | 7f199f3dfd4b6abdb2d4aa27acef6b31be575c77 /libcxxabi/src/stdlib_new_delete.cpp | |
parent | b3fd276555cb96a9c70fb3fa8031ce3a4f812a0b (diff) | |
download | bcm5719-llvm-378122744886d5d6450839b30c7f4aadf4823a25.tar.gz bcm5719-llvm-378122744886d5d6450839b30c7f4aadf4823a25.zip |
Cleanup new/delete definitions
This patch cleans up how libc++abi handles the definitions for new/delete.
It is in preperation for upcoming changes to fix how both libc++ and libc++abi
handle new/delete.
The primary changes in this patch are:
* Move the definitions for bad_array_length and bad_new_array_length
into stdlib_exception.cpp. This way stdlib_new_delete.cpp only
contains new/delete.
* Rename cxa_new_delete.cpp -> stdlib_new_delete.cpp for consistency
with other files.
* Add a FIXME regarding when stdlib_new_delete.cpp is actually compiled
as part of the dylib.
llvm-svn: 296715
Diffstat (limited to 'libcxxabi/src/stdlib_new_delete.cpp')
-rw-r--r-- | libcxxabi/src/stdlib_new_delete.cpp | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/libcxxabi/src/stdlib_new_delete.cpp b/libcxxabi/src/stdlib_new_delete.cpp new file mode 100644 index 00000000000..45c6b174a5c --- /dev/null +++ b/libcxxabi/src/stdlib_new_delete.cpp @@ -0,0 +1,178 @@ +//===------------------------ cxa_new_delete.cpp --------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +// +// This file implements the new and delete operators. +//===----------------------------------------------------------------------===// + +#define _LIBCPP_BUILDING_NEW + +#include "__cxxabi_config.h" +#include <new> +#include <cstdlib> + +#if !defined(_THROW_BAD_ALLOC) || !defined(_NOEXCEPT) +#error _THROW_BAD_ALLOC and _NOEXCEPT libc++ macros must already be defined \ + by libc++. +#endif + +/* +[new.delete.single] + +* Executes a loop: Within the loop, the function first attempts to allocate + the requested storage. Whether the attempt involves a call to the Standard C + library function malloc is unspecified. + +* Returns a pointer to the allocated storage if the attempt is successful. + Otherwise, if the current new_handler (18.6.2.5) is a null pointer value, + throws bad_alloc. + +* Otherwise, the function calls the current new_handler function (18.6.2.3). + If the called function returns, the loop repeats. + +* The loop terminates when an attempt to allocate the requested storage is + successful or when a called new_handler function does not return. +*/ +_LIBCXXABI_WEAK +void * +operator new(std::size_t size) _THROW_BAD_ALLOC +{ + if (size == 0) + size = 1; + void* p; + while ((p = std::malloc(size)) == 0) + { + 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; +} + +/* +Note: The relationships among these operators is both carefully considered +and standard in C++11. Please do not change them without fully understanding +the consequences of doing so. Reference: +http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2158.html +*/ +/* +[new.delete.single] + +Calls operator new(size). If the call returns normally, returns the result of +that call. Otherwise, returns a null pointer. +*/ +_LIBCXXABI_WEAK +void* +operator new(size_t size, const std::nothrow_t&) _NOEXCEPT +{ + void* p = 0; +#ifndef _LIBCXXABI_NO_EXCEPTIONS + try + { +#endif + p = ::operator new(size); +#ifndef _LIBCXXABI_NO_EXCEPTIONS + } + catch (...) + { + } +#endif + return p; +} + +/* +[new.delete.array] + +Returns operator new(size). +*/ +_LIBCXXABI_WEAK +void* +operator new[](size_t size) _THROW_BAD_ALLOC +{ + return ::operator new(size); +} + +/* +[new.delete.array] + +Calls operator new[](size). If the call returns normally, returns the result +of that call. Otherwise, returns a null pointer. +*/ +_LIBCXXABI_WEAK +void* +operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT +{ + void* p = 0; +#ifndef _LIBCXXABI_NO_EXCEPTIONS + try + { +#endif + p = ::operator new[](size); +#ifndef _LIBCXXABI_NO_EXCEPTIONS + } + catch (...) + { + } +#endif + return p; +} + +/* +[new.delete.single] + +If ptr is null, does nothing. Otherwise, reclaims the storage allocated by the +earlier call to operator new. +*/ +_LIBCXXABI_WEAK +void +operator delete(void* ptr) _NOEXCEPT +{ + if (ptr) + std::free(ptr); +} + +/* +[new.delete.single] + +calls operator delete(ptr) +*/ +_LIBCXXABI_WEAK +void +operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT +{ + ::operator delete(ptr); +} + +/* +[new.delete.array] + +Calls operator delete(ptr) +*/ +_LIBCXXABI_WEAK +void +operator delete[] (void* ptr) _NOEXCEPT +{ + ::operator delete(ptr); +} + +/* +[new.delete.array] + +calls operator delete[](ptr) +*/ +_LIBCXXABI_WEAK +void +operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT +{ + ::operator delete[](ptr); +} |