Commit 42da1d385d

Andrew Kelley <andrew@ziglang.org>
2020-08-05 02:30:57
libcxxabi: upgrade from llvm 10 to 11rc1
1 parent 54b67c2
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