libcxxabi: upgrade from llvm 10 to 11rc1

This commit is contained in:
Andrew Kelley 2020-08-04 17:30:57 -07:00
parent 54b67c2025
commit 42da1d385d
11 changed files with 406 additions and 134 deletions

View File

@ -76,4 +76,12 @@
# define _LIBCXXABI_GUARD_ABI_ARM # define _LIBCXXABI_GUARD_ABI_ARM
#endif #endif
#if defined(_LIBCXXABI_COMPILER_CLANG)
# if !__has_feature(cxx_exceptions)
# define _LIBCXXABI_NO_EXCEPTIONS
# endif
#elif defined(_LIBCXXABI_COMPILER_GCC) && !__EXCEPTIONS
# define _LIBCXXABI_NO_EXCEPTIONS
#endif
#endif // ____CXXABI_CONFIG_H #endif // ____CXXABI_CONFIG_H

View File

@ -12,52 +12,54 @@
#include "abort_message.h" #include "abort_message.h"
#ifdef __BIONIC__ #ifdef __BIONIC__
#include <android/api-level.h> # include <android/api-level.h>
#if __ANDROID_API__ >= 21 # if __ANDROID_API__ >= 21
#include <syslog.h> # include <syslog.h>
extern "C" void android_set_abort_message(const char* msg); extern "C" void android_set_abort_message(const char* msg);
#else # else
#include <assert.h> # include <assert.h>
#endif // __ANDROID_API__ >= 21 # endif // __ANDROID_API__ >= 21
#endif // __BIONIC__ #endif // __BIONIC__
#ifdef __APPLE__ #if defined(__APPLE__) && __has_include(<CrashReporterClient.h>)
# if defined(__has_include) && __has_include(<CrashReporterClient.h>) # include <CrashReporterClient.h>
# define HAVE_CRASHREPORTERCLIENT_H # define _LIBCXXABI_USE_CRASHREPORTER_CLIENT
# include <CrashReporterClient.h>
# endif
#endif #endif
void abort_message(const char* format, ...) void abort_message(const char* format, ...)
{ {
// write message to stderr // Write message to stderr. We do this before formatting into a
// variable-size buffer so that we still get some information if
// formatting into the variable-sized buffer fails.
#if !defined(NDEBUG) || !defined(LIBCXXABI_BAREMETAL) #if !defined(NDEBUG) || !defined(LIBCXXABI_BAREMETAL)
#ifdef __APPLE__ {
fprintf(stderr, "libc++abi.dylib: "); fprintf(stderr, "libc++abi: ");
#endif va_list list;
va_list list; va_start(list, format);
va_start(list, format); vfprintf(stderr, format, list);
vfprintf(stderr, format, list); va_end(list);
va_end(list); fprintf(stderr, "\n");
fprintf(stderr, "\n"); }
#endif #endif
#if defined(__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H) // Format the arguments into an allocated buffer. We leak the buffer on
// record message in crash report // purpose, since we're about to abort() anyway.
#if defined(_LIBCXXABI_USE_CRASHREPORTER_CLIENT)
char* buffer; char* buffer;
va_list list2; va_list list;
va_start(list2, format); va_start(list, format);
vasprintf(&buffer, format, list2); vasprintf(&buffer, format, list);
va_end(list2); va_end(list);
CRSetCrashLogMessage(buffer); CRSetCrashLogMessage(buffer);
#elif defined(__BIONIC__) #elif defined(__BIONIC__)
char* buffer; char* buffer;
va_list list2; va_list list;
va_start(list2, format); va_start(list, format);
vasprintf(&buffer, format, list2); vasprintf(&buffer, format, list);
va_end(list2); va_end(list);
#if __ANDROID_API__ >= 21 # if __ANDROID_API__ >= 21
// Show error in tombstone. // Show error in tombstone.
android_set_abort_message(buffer); android_set_abort_message(buffer);
@ -65,12 +67,12 @@ void abort_message(const char* format, ...)
openlog("libc++abi", 0, 0); openlog("libc++abi", 0, 0);
syslog(LOG_CRIT, "%s", buffer); syslog(LOG_CRIT, "%s", buffer);
closelog(); closelog();
#else # else
// The good error reporting wasn't available in Android until L. Since we're // The good error reporting wasn't available in Android until L. Since we're
// about to abort anyway, just call __assert2, which will log _somewhere_ // about to abort anyway, just call __assert2, which will log _somewhere_
// (tombstone and/or logcat) in older releases. // (tombstone and/or logcat) in older releases.
__assert2(__FILE__, __LINE__, __func__, buffer); __assert2(__FILE__, __LINE__, __func__, buffer);
#endif // __ANDROID_API__ >= 21 # endif // __ANDROID_API__ >= 21
#endif // __BIONIC__ #endif // __BIONIC__
abort(); abort();

View File

@ -11,16 +11,7 @@
#include "cxxabi.h" #include "cxxabi.h"
#ifdef __cplusplus extern "C" _LIBCXXABI_HIDDEN _LIBCXXABI_NORETURN void
extern "C" {
#endif
_LIBCXXABI_HIDDEN _LIBCXXABI_NORETURN void
abort_message(const char *format, ...) __attribute__((format(printf, 1, 2))); abort_message(const char *format, ...) __attribute__((format(printf, 1, 2)));
#ifdef __cplusplus
}
#endif #endif
#endif

View File

@ -40,7 +40,6 @@
#include "__cxxabi_config.h" #include "__cxxabi_config.h"
#include "include/atomic_support.h" #include "include/atomic_support.h"
#include <unistd.h> #include <unistd.h>
#include <sys/types.h>
#if defined(__has_include) #if defined(__has_include)
# if __has_include(<sys/syscall.h>) # if __has_include(<sys/syscall.h>)
# include <sys/syscall.h> # include <sys/syscall.h>
@ -108,6 +107,32 @@ struct LazyValue {
bool is_init = false; bool is_init = false;
}; };
template <class IntType>
class AtomicInt {
public:
using MemoryOrder = std::__libcpp_atomic_order;
explicit AtomicInt(IntType *b) : b(b) {}
AtomicInt(AtomicInt const&) = delete;
AtomicInt& operator=(AtomicInt const&) = delete;
IntType load(MemoryOrder ord) {
return std::__libcpp_atomic_load(b, ord);
}
void store(IntType val, MemoryOrder ord) {
std::__libcpp_atomic_store(b, val, ord);
}
IntType exchange(IntType new_val, MemoryOrder ord) {
return std::__libcpp_atomic_exchange(b, new_val, ord);
}
bool compare_exchange(IntType *expected, IntType desired, MemoryOrder ord_success, MemoryOrder ord_failure) {
return std::__libcpp_atomic_compare_exchange(b, expected, desired, ord_success, ord_failure);
}
private:
IntType *b;
};
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// PlatformGetThreadID // PlatformGetThreadID
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -195,7 +220,7 @@ public:
public: public:
/// base_address - the address of the original guard object. /// base_address - the address of the original guard object.
void* const base_address; void* const base_address;
/// The address of the guord byte at offset 0. /// The address of the guard byte at offset 0.
uint8_t* const guard_byte_address; uint8_t* const guard_byte_address;
/// The address of the byte used by the implementation during initialization. /// The address of the byte used by the implementation during initialization.
uint8_t* const init_byte_address; uint8_t* const init_byte_address;

View File

@ -12,7 +12,7 @@
#ifndef _CXA_HANDLERS_H #ifndef _CXA_HANDLERS_H
#define _CXA_HANDLERS_H #define _CXA_HANDLERS_H
#include <__cxxabi_config.h> #include "__cxxabi_config.h"
#include <exception> #include <exception>

View File

@ -1,22 +0,0 @@
//===------------------------- cxa_unexpected.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
//
//===----------------------------------------------------------------------===//
#include <exception>
#include "cxxabi.h"
#include "cxa_exception.h"
namespace __cxxabiv1
{
extern "C"
{
}
} // namespace __cxxabiv1

View File

@ -24,9 +24,9 @@
namespace __cxxabiv1 { namespace __cxxabiv1 {
#if 0 //
#pragma mark --Helper routines and classes -- // Helper routines and classes
#endif //
namespace { namespace {
inline static size_t __get_element_count ( void *p ) { inline static size_t __get_element_count ( void *p ) {
@ -111,9 +111,9 @@ namespace {
}; };
} }
#if 0 //
#pragma mark --Externally visible routines-- // Externally visible routines
#endif //
namespace { namespace {
_LIBCXXABI_NORETURN _LIBCXXABI_NORETURN

View File

@ -98,7 +98,7 @@
X(BoolExpr) \ X(BoolExpr) \
X(StringLiteral) \ X(StringLiteral) \
X(LambdaExpr) \ X(LambdaExpr) \
X(IntegerCastExpr) \ X(EnumLiteral) \
X(IntegerLiteral) \ X(IntegerLiteral) \
X(FloatLiteral) \ X(FloatLiteral) \
X(DoubleLiteral) \ X(DoubleLiteral) \
@ -2036,22 +2036,26 @@ public:
} }
}; };
class IntegerCastExpr : public Node { class EnumLiteral : public Node {
// ty(integer) // ty(integer)
const Node *Ty; const Node *Ty;
StringView Integer; StringView Integer;
public: public:
IntegerCastExpr(const Node *Ty_, StringView Integer_) EnumLiteral(const Node *Ty_, StringView Integer_)
: Node(KIntegerCastExpr), Ty(Ty_), Integer(Integer_) {} : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {}
template<typename Fn> void match(Fn F) const { F(Ty, Integer); } template<typename Fn> void match(Fn F) const { F(Ty, Integer); }
void printLeft(OutputStream &S) const override { void printLeft(OutputStream &S) const override {
S += "("; S << "(";
Ty->print(S); Ty->print(S);
S += ")"; S << ")";
S += Integer;
if (Integer[0] == 'n')
S << "-" << Integer.dropFront(1);
else
S << Integer;
} }
}; };
@ -4064,8 +4068,11 @@ Qualifiers AbstractManglingParser<Alloc, Derived>::parseCVQualifiers() {
// ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters // ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter // ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters // ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
// ::= fpT # 'this' expression (not part of standard?)
template <typename Derived, typename Alloc> template <typename Derived, typename Alloc>
Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() { Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
if (consumeIf("fpT"))
return make<NameType>("this");
if (consumeIf("fp")) { if (consumeIf("fp")) {
parseCVQualifiers(); parseCVQualifiers();
StringView Num = parseNumber(); StringView Num = parseNumber();
@ -4225,7 +4232,13 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
return getDerived().template parseFloatingLiteral<double>(); return getDerived().template parseFloatingLiteral<double>();
case 'e': case 'e':
++First; ++First;
#if defined(__powerpc__) || defined(__s390__)
// Handle cases where long doubles encoded with e have the same size
// and representation as doubles.
return getDerived().template parseFloatingLiteral<double>();
#else
return getDerived().template parseFloatingLiteral<long double>(); return getDerived().template parseFloatingLiteral<long double>();
#endif
case '_': case '_':
if (consumeIf("_Z")) { if (consumeIf("_Z")) {
Node *R = getDerived().parseEncoding(); Node *R = getDerived().parseEncoding();
@ -4264,12 +4277,12 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
Node *T = getDerived().parseType(); Node *T = getDerived().parseType();
if (T == nullptr) if (T == nullptr)
return nullptr; return nullptr;
StringView N = parseNumber(); StringView N = parseNumber(/*AllowNegative=*/true);
if (N.empty()) if (N.empty())
return nullptr; return nullptr;
if (!consumeIf('E')) if (!consumeIf('E'))
return nullptr; return nullptr;
return make<IntegerCastExpr>(T, N); return make<EnumLiteral>(T, N);
} }
} }
} }
@ -5083,6 +5096,22 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
// ::= <special-name> // ::= <special-name>
template <typename Derived, typename Alloc> template <typename Derived, typename Alloc>
Node *AbstractManglingParser<Derived, Alloc>::parseEncoding() { Node *AbstractManglingParser<Derived, Alloc>::parseEncoding() {
// The template parameters of an encoding are unrelated to those of the
// enclosing context.
class SaveTemplateParams {
AbstractManglingParser *Parser;
decltype(TemplateParams) OldParams;
public:
SaveTemplateParams(AbstractManglingParser *Parser) : Parser(Parser) {
OldParams = std::move(Parser->TemplateParams);
Parser->TemplateParams.clear();
}
~SaveTemplateParams() {
Parser->TemplateParams = std::move(OldParams);
}
} SaveTemplateParams(this);
if (look() == 'G' || look() == 'T') if (look() == 'G' || look() == 'T')
return getDerived().parseSpecialName(); return getDerived().parseSpecialName();

View File

@ -177,34 +177,4 @@ bool __libcpp_atomic_compare_exchange(_ValueType* __val,
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
namespace {
template <class IntType>
class AtomicInt {
public:
using MemoryOrder = std::__libcpp_atomic_order;
explicit AtomicInt(IntType *b) : b(b) {}
AtomicInt(AtomicInt const&) = delete;
AtomicInt& operator=(AtomicInt const&) = delete;
IntType load(MemoryOrder ord) {
return std::__libcpp_atomic_load(b, ord);
}
void store(IntType val, MemoryOrder ord) {
std::__libcpp_atomic_store(b, val, ord);
}
IntType exchange(IntType new_val, MemoryOrder ord) {
return std::__libcpp_atomic_exchange(b, new_val, ord);
}
bool compare_exchange(IntType *expected, IntType desired, MemoryOrder ord_success, MemoryOrder ord_failure) {
return std::__libcpp_atomic_compare_exchange(b, expected, desired, ord_success, ord_failure);
}
private:
IntType *b;
};
} // end namespace
#endif // ATOMIC_SUPPORT_H #endif // ATOMIC_SUPPORT_H

View File

@ -8,11 +8,11 @@
#include "private_typeinfo.h" #include "private_typeinfo.h"
// The flag _LIBCXX_DYNAMIC_FALLBACK is used to make dynamic_cast more // The flag _LIBCXXABI_FORGIVING_DYNAMIC_CAST is used to make dynamic_cast
// forgiving when type_info's mistakenly have hidden visibility and thus // more forgiving when type_info's mistakenly have hidden visibility and
// multiple type_infos can exist for a single type. // thus multiple type_infos can exist for a single type.
// //
// When _LIBCXX_DYNAMIC_FALLBACK is defined, and only in the case where // When _LIBCXXABI_FORGIVING_DYNAMIC_CAST is defined, and only in the case where
// there is a detected inconsistency in the type_info hierarchy during a // there is a detected inconsistency in the type_info hierarchy during a
// dynamic_cast, then the equality operation will fall back to using strcmp // dynamic_cast, then the equality operation will fall back to using strcmp
// on type_info names to determine type_info equality. // on type_info names to determine type_info equality.
@ -23,7 +23,7 @@
// algorithm and an inconsistency is still detected, dynamic_cast will call // algorithm and an inconsistency is still detected, dynamic_cast will call
// abort with an appropriate message. // abort with an appropriate message.
// //
// The current implementation of _LIBCXX_DYNAMIC_FALLBACK requires a // The current implementation of _LIBCXXABI_FORGIVING_DYNAMIC_CAST requires a
// printf-like function called syslog: // printf-like function called syslog:
// //
// void syslog(int facility_priority, const char* format, ...); // void syslog(int facility_priority, const char* format, ...);
@ -31,21 +31,22 @@
// If you want this functionality but your platform doesn't have syslog, // If you want this functionality but your platform doesn't have syslog,
// just implement it in terms of fprintf(stderr, ...). // just implement it in terms of fprintf(stderr, ...).
// //
// _LIBCXX_DYNAMIC_FALLBACK is currently off by default. // _LIBCXXABI_FORGIVING_DYNAMIC_CAST is currently off by default.
// On Windows, typeids are different between DLLs and EXEs, so comparing // On Windows, typeids are different between DLLs and EXEs, so comparing
// type_info* will work for typeids from the same compiled file but fail // type_info* will work for typeids from the same compiled file but fail
// for typeids from a DLL and an executable. Among other things, exceptions // for typeids from a DLL and an executable. Among other things, exceptions
// are not caught by handlers since can_catch() returns false. // are not caught by handlers since can_catch() returns false.
// //
// Defining _LIBCXX_DYNAMIC_FALLBACK does not help since can_catch() calls // Defining _LIBCXXABI_FORGIVING_DYNAMIC_CAST does not help since can_catch() calls
// is_equal() with use_strcmp=false so the string names are not compared. // is_equal() with use_strcmp=false so the string names are not compared.
#include <string.h> #include <string.h>
#ifdef _LIBCXX_DYNAMIC_FALLBACK #ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST
#include "abort_message.h" #include "abort_message.h"
#include <sys/syslog.h> #include <sys/syslog.h>
#include <atomic>
#endif #endif
static inline static inline
@ -633,22 +634,25 @@ __dynamic_cast(const void *static_ptr, const __class_type_info *static_type,
info.number_of_dst_type = 1; info.number_of_dst_type = 1;
// Do the search // Do the search
dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, false); dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, false);
#ifdef _LIBCXX_DYNAMIC_FALLBACK #ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST
// The following if should always be false because we should definitely // The following if should always be false because we should definitely
// find (static_ptr, static_type), either on a public or private path // find (static_ptr, static_type), either on a public or private path
if (info.path_dst_ptr_to_static_ptr == unknown) if (info.path_dst_ptr_to_static_ptr == unknown)
{ {
// We get here only if there is some kind of visibility problem // We get here only if there is some kind of visibility problem
// in client code. // in client code.
syslog(LOG_ERR, "dynamic_cast error 1: Both of the following type_info's " static std::atomic<size_t> error_count(0);
"should have public visibility. At least one of them is hidden. %s" size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed);
", %s.\n", static_type->name(), dynamic_type->name()); if ((error_count_snapshot & (error_count_snapshot-1)) == 0)
syslog(LOG_ERR, "dynamic_cast error 1: Both of the following type_info's "
"should have public visibility. At least one of them is hidden. %s"
", %s.\n", static_type->name(), dynamic_type->name());
// Redo the search comparing type_info's using strcmp // Redo the search comparing type_info's using strcmp
info = {dst_type, static_ptr, static_type, src2dst_offset, 0}; info = {dst_type, static_ptr, static_type, src2dst_offset, 0};
info.number_of_dst_type = 1; info.number_of_dst_type = 1;
dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, true); dynamic_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, true);
} }
#endif // _LIBCXX_DYNAMIC_FALLBACK #endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST
// Query the search. // Query the search.
if (info.path_dst_ptr_to_static_ptr == public_path) if (info.path_dst_ptr_to_static_ptr == public_path)
dst_ptr = dynamic_ptr; dst_ptr = dynamic_ptr;
@ -657,22 +661,25 @@ __dynamic_cast(const void *static_ptr, const __class_type_info *static_type,
{ {
// Not using giant short cut. Do the search // Not using giant short cut. Do the search
dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, false); dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, false);
#ifdef _LIBCXX_DYNAMIC_FALLBACK #ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST
// The following if should always be false because we should definitely // The following if should always be false because we should definitely
// find (static_ptr, static_type), either on a public or private path // find (static_ptr, static_type), either on a public or private path
if (info.path_dst_ptr_to_static_ptr == unknown && if (info.path_dst_ptr_to_static_ptr == unknown &&
info.path_dynamic_ptr_to_static_ptr == unknown) info.path_dynamic_ptr_to_static_ptr == unknown)
{ {
syslog(LOG_ERR, "dynamic_cast error 2: One or more of the following type_info's " static std::atomic<size_t> error_count(0);
"has hidden visibility or is defined in more than one translation " size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed);
"unit. They should all have public visibility. " if ((error_count_snapshot & (error_count_snapshot-1)) == 0)
"%s, %s, %s.\n", static_type->name(), dynamic_type->name(), syslog(LOG_ERR, "dynamic_cast error 2: One or more of the following type_info's "
dst_type->name()); "has hidden visibility or is defined in more than one translation "
"unit. They should all have public visibility. "
"%s, %s, %s.\n", static_type->name(), dynamic_type->name(),
dst_type->name());
// Redo the search comparing type_info's using strcmp // Redo the search comparing type_info's using strcmp
info = {dst_type, static_ptr, static_type, src2dst_offset, 0}; info = {dst_type, static_ptr, static_type, src2dst_offset, 0};
dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, true); dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, true);
} }
#endif // _LIBCXX_DYNAMIC_FALLBACK #endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST
// Query the search. // Query the search.
switch (info.number_to_static_ptr) switch (info.number_to_static_ptr)
{ {

View File

@ -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