Commit 42da1d385d
Changed files (11)
lib/libcxxabi/include/__cxxabi_config.h
@@ -76,4 +76,12 @@
# define _LIBCXXABI_GUARD_ABI_ARM
#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
lib/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -98,7 +98,7 @@
X(BoolExpr) \
X(StringLiteral) \
X(LambdaExpr) \
- X(IntegerCastExpr) \
+ X(EnumLiteral) \
X(IntegerLiteral) \
X(FloatLiteral) \
X(DoubleLiteral) \
@@ -2036,22 +2036,26 @@ public:
}
};
-class IntegerCastExpr : public Node {
+class EnumLiteral : public Node {
// ty(integer)
const Node *Ty;
StringView Integer;
public:
- IntegerCastExpr(const Node *Ty_, StringView Integer_)
- : Node(KIntegerCastExpr), Ty(Ty_), Integer(Integer_) {}
+ EnumLiteral(const Node *Ty_, StringView Integer_)
+ : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {}
template<typename Fn> void match(Fn F) const { F(Ty, Integer); }
void printLeft(OutputStream &S) const override {
- S += "(";
+ S << "(";
Ty->print(S);
- S += ")";
- S += Integer;
+ S << ")";
+
+ 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
// ::= 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
+// ::= fpT # 'this' expression (not part of standard?)
template <typename Derived, typename Alloc>
Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
+ if (consumeIf("fpT"))
+ return make<NameType>("this");
if (consumeIf("fp")) {
parseCVQualifiers();
StringView Num = parseNumber();
@@ -4225,7 +4232,13 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
return getDerived().template parseFloatingLiteral<double>();
case 'e':
++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>();
+#endif
case '_':
if (consumeIf("_Z")) {
Node *R = getDerived().parseEncoding();
@@ -4264,12 +4277,12 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
Node *T = getDerived().parseType();
if (T == nullptr)
return nullptr;
- StringView N = parseNumber();
+ StringView N = parseNumber(/*AllowNegative=*/true);
if (N.empty())
return nullptr;
if (!consumeIf('E'))
return nullptr;
- return make<IntegerCastExpr>(T, N);
+ return make<EnumLiteral>(T, N);
}
}
}
@@ -5083,6 +5096,22 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
// ::= <special-name>
template <typename Derived, typename Alloc>
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')
return getDerived().parseSpecialName();
lib/libcxxabi/src/include/atomic_support.h
@@ -177,34 +177,4 @@ bool __libcpp_atomic_compare_exchange(_ValueType* __val,
_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
lib/libcxxabi/src/abort_message.cpp
@@ -12,52 +12,54 @@
#include "abort_message.h"
#ifdef __BIONIC__
-#include <android/api-level.h>
-#if __ANDROID_API__ >= 21
-#include <syslog.h>
-extern "C" void android_set_abort_message(const char* msg);
-#else
-#include <assert.h>
-#endif // __ANDROID_API__ >= 21
+# include <android/api-level.h>
+# if __ANDROID_API__ >= 21
+# include <syslog.h>
+ extern "C" void android_set_abort_message(const char* msg);
+# else
+# include <assert.h>
+# endif // __ANDROID_API__ >= 21
#endif // __BIONIC__
-#ifdef __APPLE__
-# if defined(__has_include) && __has_include(<CrashReporterClient.h>)
-# define HAVE_CRASHREPORTERCLIENT_H
-# include <CrashReporterClient.h>
-# endif
+#if defined(__APPLE__) && __has_include(<CrashReporterClient.h>)
+# include <CrashReporterClient.h>
+# define _LIBCXXABI_USE_CRASHREPORTER_CLIENT
#endif
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)
-#ifdef __APPLE__
- fprintf(stderr, "libc++abi.dylib: ");
+ {
+ fprintf(stderr, "libc++abi: ");
+ va_list list;
+ va_start(list, format);
+ vfprintf(stderr, format, list);
+ va_end(list);
+ fprintf(stderr, "\n");
+ }
#endif
+
+ // Format the arguments into an allocated buffer. We leak the buffer on
+ // purpose, since we're about to abort() anyway.
+#if defined(_LIBCXXABI_USE_CRASHREPORTER_CLIENT)
+ char* buffer;
va_list list;
va_start(list, format);
- vfprintf(stderr, format, list);
+ vasprintf(&buffer, format, list);
va_end(list);
- fprintf(stderr, "\n");
-#endif
-#if defined(__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H)
- // record message in crash report
- char* buffer;
- va_list list2;
- va_start(list2, format);
- vasprintf(&buffer, format, list2);
- va_end(list2);
CRSetCrashLogMessage(buffer);
#elif defined(__BIONIC__)
char* buffer;
- va_list list2;
- va_start(list2, format);
- vasprintf(&buffer, format, list2);
- va_end(list2);
+ va_list list;
+ va_start(list, format);
+ vasprintf(&buffer, format, list);
+ va_end(list);
-#if __ANDROID_API__ >= 21
+# if __ANDROID_API__ >= 21
// Show error in tombstone.
android_set_abort_message(buffer);
@@ -65,12 +67,12 @@ void abort_message(const char* format, ...)
openlog("libc++abi", 0, 0);
syslog(LOG_CRIT, "%s", buffer);
closelog();
-#else
+# else
// 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_
// (tombstone and/or logcat) in older releases.
__assert2(__FILE__, __LINE__, __func__, buffer);
-#endif // __ANDROID_API__ >= 21
+# endif // __ANDROID_API__ >= 21
#endif // __BIONIC__
abort();
lib/libcxxabi/src/abort_message.h
@@ -11,16 +11,7 @@
#include "cxxabi.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-_LIBCXXABI_HIDDEN _LIBCXXABI_NORETURN void
+extern "C" _LIBCXXABI_HIDDEN _LIBCXXABI_NORETURN void
abort_message(const char *format, ...) __attribute__((format(printf, 1, 2)));
-#ifdef __cplusplus
-}
#endif
-
-#endif
-
lib/libcxxabi/src/cxa_guard_impl.h
@@ -40,7 +40,6 @@
#include "__cxxabi_config.h"
#include "include/atomic_support.h"
#include <unistd.h>
-#include <sys/types.h>
#if defined(__has_include)
# if __has_include(<sys/syscall.h>)
# include <sys/syscall.h>
@@ -108,6 +107,32 @@ struct LazyValue {
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
//===----------------------------------------------------------------------===//
@@ -195,7 +220,7 @@ public:
public:
/// base_address - the address of the original guard object.
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;
/// The address of the byte used by the implementation during initialization.
uint8_t* const init_byte_address;
lib/libcxxabi/src/cxa_handlers.h
@@ -12,7 +12,7 @@
#ifndef _CXA_HANDLERS_H
#define _CXA_HANDLERS_H
-#include <__cxxabi_config.h>
+#include "__cxxabi_config.h"
#include <exception>
lib/libcxxabi/src/cxa_unexpected.cpp
@@ -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
-
lib/libcxxabi/src/cxa_vector.cpp
@@ -24,9 +24,9 @@
namespace __cxxabiv1 {
-#if 0
-#pragma mark --Helper routines and classes --
-#endif
+//
+// Helper routines and classes
+//
namespace {
inline static size_t __get_element_count ( void *p ) {
@@ -111,9 +111,9 @@ namespace {
};
}
-#if 0
-#pragma mark --Externally visible routines--
-#endif
+//
+// Externally visible routines
+//
namespace {
_LIBCXXABI_NORETURN
lib/libcxxabi/src/private_typeinfo.cpp
@@ -8,11 +8,11 @@
#include "private_typeinfo.h"
-// The flag _LIBCXX_DYNAMIC_FALLBACK is used to make dynamic_cast more
-// forgiving when type_info's mistakenly have hidden visibility and thus
-// multiple type_infos can exist for a single type.
+// The flag _LIBCXXABI_FORGIVING_DYNAMIC_CAST is used to make dynamic_cast
+// more forgiving when type_info's mistakenly have hidden visibility and
+// 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
// dynamic_cast, then the equality operation will fall back to using strcmp
// on type_info names to determine type_info equality.
@@ -23,7 +23,7 @@
// algorithm and an inconsistency is still detected, dynamic_cast will call
// 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:
//
// void syslog(int facility_priority, const char* format, ...);
@@ -31,21 +31,22 @@
// If you want this functionality but your platform doesn't have syslog,
// 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
// 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
// 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.
#include <string.h>
-#ifdef _LIBCXX_DYNAMIC_FALLBACK
+#ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST
#include "abort_message.h"
#include <sys/syslog.h>
+#include <atomic>
#endif
static inline
@@ -633,22 +634,25 @@ __dynamic_cast(const void *static_ptr, const __class_type_info *static_type,
info.number_of_dst_type = 1;
// Do the search
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
// find (static_ptr, static_type), either on a public or private path
if (info.path_dst_ptr_to_static_ptr == unknown)
{
// We get here only if there is some kind of visibility problem
// in client code.
- 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());
+ static std::atomic<size_t> error_count(0);
+ size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed);
+ 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
info = {dst_type, static_ptr, static_type, src2dst_offset, 0};
info.number_of_dst_type = 1;
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.
if (info.path_dst_ptr_to_static_ptr == public_path)
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
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
// find (static_ptr, static_type), either on a public or private path
if (info.path_dst_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 "
- "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());
+ static std::atomic<size_t> error_count(0);
+ size_t error_count_snapshot = error_count.fetch_add(1, std::memory_order_relaxed);
+ if ((error_count_snapshot & (error_count_snapshot-1)) == 0)
+ syslog(LOG_ERR, "dynamic_cast error 2: One or more of the following type_info's "
+ "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
info = {dst_type, static_ptr, static_type, src2dst_offset, 0};
dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, true);
}
-#endif // _LIBCXX_DYNAMIC_FALLBACK
+#endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST
// Query the search.
switch (info.number_to_static_ptr)
{
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