EricWF created this revision.
EricWF added reviewers: mclow.lists, rsmith.
EricWF added subscribers: cfe-commits, rsmith.

This patch implements the library side of P0035R4. The implementation is thanks 
to @rsmith.

In addition to the C++17 implementation, the library implementation can be 
explicitly turned on using `-faligned-allocation` in all dialects.


https://reviews.llvm.org/D25591

Files:
  include/new
  lib/abi/CHANGELOG.TXT
  lib/abi/x86_64-linux-gnu.abilist
  src/new.cpp
  test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp
  test/libcxx/test/config.py
  test/std/language.support/support.dynamic/align_val_t.pass.cpp
  
test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp
  
test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp
  
test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp
  
test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp
  
test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp
  
test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp
  
test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp
  
test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp
  
test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp
  
test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp

Index: test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp
===================================================================
--- /dev/null
+++ test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// test operator new replacement
+
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cstdint>
+#include <cassert>
+#include <limits>
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+bool A_constructed = false;
+
+struct alignas(OverAligned) A {
+    A() {A_constructed = true;}
+    ~A() {A_constructed = false;}
+};
+
+
+bool B_constructed = false;
+
+struct alignas(std::max_align_t) B
+{
+    std::max_align_t member;
+    B() {B_constructed = true;}
+    ~B() {B_constructed = false;}
+};
+
+int new_called = 0;
+
+alignas(OverAligned) char DummyData[OverAligned];
+
+void* operator new(std::size_t s, std::align_val_t a) throw(std::bad_alloc)
+{
+    assert(new_called == 0); // We already allocated
+    assert(s <= sizeof(DummyData));
+    assert(static_cast<std::size_t>(a) == OverAligned);
+    ++new_called;
+    return DummyData;
+}
+
+void  operator delete(void* p, std::align_val_t a) throw()
+{
+    assert(new_called == 1);
+    --new_called;
+    assert(p == DummyData);
+}
+
+
+int main()
+{
+    {
+        A* ap = new A;
+        assert(ap);
+        assert(A_constructed);
+        assert(new_called);
+        delete ap;
+        assert(!A_constructed);
+        assert(!new_called);
+    }
+    {
+        B* bp = new B;
+        assert(bp);
+        assert(B_constructed);
+        assert(!new_called);
+        delete bp;
+        assert(!new_called);
+    }
+}
Index: test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp
===================================================================
--- /dev/null
+++ test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// test operator new nothrow by replacing only operator new
+
+// UNSUPPORTED: sanitizer-new-delete
+
+// TODO Investigate why UBSAN prevents nothrow new from calling our replacement.
+// XFAIL: ubsan
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <limits>
+
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+bool A_constructed = false;
+
+struct alignas(OverAligned) A
+{
+    A() {A_constructed = true;}
+    ~A() {A_constructed = false;}
+};
+
+bool B_constructed = false;
+
+struct B {
+  std::max_align_t  member;
+  B() { B_constructed = true; }
+  ~B() { B_constructed = false; }
+};
+
+int new_called = 0;
+alignas(OverAligned) char Buff[OverAligned * 2];
+
+void* operator new(std::size_t s, std::align_val_t a) throw(std::bad_alloc)
+{
+    assert(!new_called);
+    assert(s <= sizeof(Buff));
+    assert(static_cast<std::size_t>(a) == OverAligned);
+    ++new_called;
+    return Buff;
+}
+
+void  operator delete(void* p, std::align_val_t a) throw()
+{
+    assert(p == Buff);
+    assert(static_cast<std::size_t>(a) == OverAligned);
+    assert(new_called);
+    --new_called;
+}
+
+
+int main()
+{
+    {
+        A* ap = new (std::nothrow) A;
+        assert(ap);
+        assert(A_constructed);
+        assert(new_called);
+        delete ap;
+        assert(!A_constructed);
+        assert(!new_called);
+    }
+    {
+        B* bp = new (std::nothrow) B;
+        assert(bp);
+        assert(B_constructed);
+        assert(!new_called);
+        delete bp;
+        assert(!new_called);
+        assert(!B_constructed);
+    }
+}
Index: test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp
===================================================================
--- /dev/null
+++ test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// test operator new (nothrow)
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cstdint>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+int new_handler_called = 0;
+
+void new_handler()
+{
+    ++new_handler_called;
+    std::set_new_handler(0);
+}
+
+bool A_constructed = false;
+
+struct alignas(OverAligned) A
+{
+    A() {A_constructed = true;}
+    ~A() {A_constructed = false;}
+};
+
+void test_max_alloc() {
+    std::set_new_handler(new_handler);
+    auto do_test = []() {
+        void* vp = operator new (std::numeric_limits<std::size_t>::max(),
+                                 std::align_val_t(OverAligned),
+                                 std::nothrow);
+        assert(new_handler_called == 1);
+        assert(vp == 0);
+    };
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    try
+    {
+        do_test();
+    }
+    catch (...)
+    {
+        assert(false);
+    }
+#else
+    do_test();
+#endif
+}
+
+int main()
+{
+    {
+        A* ap = new(std::nothrow) A;
+        assert(ap);
+        assert(reinterpret_cast<std::uintptr_t>(ap) % OverAligned == 0);
+        assert(A_constructed);
+        delete ap;
+        assert(!A_constructed);
+    }
+    {
+        test_max_alloc();
+    }
+}
Index: test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp
===================================================================
--- /dev/null
+++ test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// test operator new
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cassert>
+#include <cstdint>
+#include <limits>
+
+#include "test_macros.h"
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+int new_handler_called = 0;
+
+void new_handler()
+{
+    ++new_handler_called;
+    std::set_new_handler(0);
+}
+
+bool A_constructed = false;
+
+struct alignas(OverAligned) A
+{
+    A() {A_constructed = true;}
+    ~A() {A_constructed = false;}
+};
+
+void test_throw_max_size() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    std::set_new_handler(new_handler);
+    try
+    {
+        void* vp = operator new (std::numeric_limits<std::size_t>::max(),
+                                 static_cast<std::align_val_t>(32));
+        ((void)vp);
+        assert(false);
+    }
+    catch (std::bad_alloc&)
+    {
+        assert(new_handler_called == 1);
+    }
+    catch (...)
+    {
+        assert(false);
+    }
+#endif
+}
+
+int main()
+{
+    {
+        A* ap = new A;
+        assert(ap);
+        assert(reinterpret_cast<std::uintptr_t>(ap) % OverAligned == 0);
+        assert(A_constructed);
+        delete ap;
+        assert(!A_constructed);
+    }
+    {
+        test_throw_max_size();
+    }
+}
Index: test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp
===================================================================
--- /dev/null
+++ test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// test aligned operator delete replacement.
+
+// UNSUPPORTED: sanitizer-new-delete, c++98, c++03, c++11, c++14
+
+// Older Clang versions do not support this
+// XFAIL: clang-3, apple-clang
+
+// None of the current GCC compilers support this.
+// XFAIL: gcc-4, gcc-5, gcc-6
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+int unsized_delete_called = 0;
+int unsized_delete_nothrow_called = 0;
+int aligned_delete_called = 0;
+
+void reset() {
+    unsized_delete_called = 0;
+    unsized_delete_nothrow_called = 0;
+    aligned_delete_called = 0;
+}
+
+void operator delete(void* p) throw()
+{
+    ++unsized_delete_called;
+    std::free(p);
+}
+
+void operator delete(void* p, const std::nothrow_t&) throw()
+{
+    ++unsized_delete_nothrow_called;
+    std::free(p);
+}
+
+void operator delete(void* p, std::align_val_t a) throw()
+{
+    ++aligned_delete_called;
+    std::free(p);
+}
+
+struct alignas(OverAligned) A {};
+struct alignas(std::max_align_t) B {};
+
+int main()
+{
+    {
+        B *x = new B;
+        assert(0 == unsized_delete_called);
+        assert(0 == unsized_delete_nothrow_called);
+        assert(0 == aligned_delete_called);
+
+        delete x;
+        assert(1 == unsized_delete_called);
+        assert(0 == unsized_delete_nothrow_called);
+        assert(0 == aligned_delete_called);
+    }
+    reset();
+    {
+        A *x = new A;
+        assert(0 == unsized_delete_called);
+        assert(0 == unsized_delete_nothrow_called);
+        assert(0 == aligned_delete_called);
+
+        delete x;
+        assert(0 == unsized_delete_called);
+        assert(0 == unsized_delete_nothrow_called);
+        assert(1 == aligned_delete_called);
+    }
+}
Index: test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp
===================================================================
--- /dev/null
+++ test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// test operator new replacement
+
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cstdint>
+#include <cassert>
+#include <limits>
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+int A_constructed = 0;
+
+struct alignas(OverAligned) A {
+    A() { ++A_constructed;}
+    ~A() { --A_constructed;}
+};
+
+
+int B_constructed = 0;
+
+struct alignas(std::max_align_t) B
+{
+    std::max_align_t member;
+    B() { ++B_constructed;}
+    ~B() { --B_constructed;}
+};
+
+int new_called = 0;
+
+alignas(OverAligned) char DummyData[OverAligned * 4];
+
+void* operator new[](std::size_t s, std::align_val_t a) throw(std::bad_alloc)
+{
+    assert(new_called == 0); // We already allocated
+    assert(s <= sizeof(DummyData));
+    assert(static_cast<std::size_t>(a) == OverAligned);
+    ++new_called;
+    return DummyData;
+}
+
+void  operator delete[](void* p, std::align_val_t a) throw()
+{
+    assert(new_called == 1);
+    --new_called;
+    assert(p == DummyData);
+}
+
+
+int main()
+{
+    {
+        A* ap = new A[3];
+        assert(ap);
+        assert(A_constructed == 3);
+        assert(new_called);
+        delete [] ap;
+        assert(!A_constructed);
+        assert(!new_called);
+    }
+    {
+        B* bp = new B[3];
+        assert(bp);
+        assert(B_constructed == 3);
+        assert(!new_called);
+        delete [] bp;
+        assert(!new_called);
+    }
+}
Index: test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp
===================================================================
--- /dev/null
+++ test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// test operator new nothrow by replacing only operator new
+
+// UNSUPPORTED: sanitizer-new-delete
+
+// TODO Investigate why UBSAN prevents nothrow new from calling our replacement.
+// XFAIL: ubsan
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <limits>
+
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+int A_constructed = 0;
+
+struct alignas(OverAligned) A
+{
+    A() {++A_constructed;}
+    ~A() {--A_constructed;}
+};
+
+int B_constructed = 0;
+
+struct B {
+  std::max_align_t member;
+  B() { ++B_constructed; }
+  ~B() { --B_constructed; }
+};
+
+int new_called = 0;
+alignas(OverAligned) char Buff[OverAligned * 3];
+
+void* operator new[](std::size_t s, std::align_val_t a) throw(std::bad_alloc)
+{
+    assert(!new_called);
+    assert(s <= sizeof(Buff));
+    assert(static_cast<std::size_t>(a) == OverAligned);
+    ++new_called;
+    return Buff;
+}
+
+void  operator delete[](void* p, std::align_val_t a) throw()
+{
+    assert(p == Buff);
+    assert(static_cast<std::size_t>(a) == OverAligned);
+    assert(new_called);
+    --new_called;
+}
+
+int main()
+{
+    {
+        A* ap = new (std::nothrow) A[2];
+        assert(ap);
+        assert(A_constructed == 2);
+        assert(new_called);
+        delete [] ap;
+        assert(A_constructed == 0);
+        assert(!new_called);
+    }
+    {
+        B* bp = new (std::nothrow) B[2];
+        assert(bp);
+        assert(B_constructed == 2);
+        assert(!new_called);
+        delete [] bp;
+        assert(!new_called);
+        assert(!B_constructed);
+    }
+}
Index: test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp
===================================================================
--- /dev/null
+++ test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// test operator new (nothrow)
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cstdint>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+int new_handler_called = 0;
+
+void new_handler()
+{
+    ++new_handler_called;
+    std::set_new_handler(0);
+}
+
+int A_constructed = 0;
+
+struct alignas(OverAligned) A
+{
+    A() { ++A_constructed; }
+    ~A() { --A_constructed; }
+};
+
+void test_max_alloc() {
+    std::set_new_handler(new_handler);
+    auto do_test = []() {
+        void* vp = operator new [](std::numeric_limits<std::size_t>::max(),
+                                 std::align_val_t(OverAligned),
+                                 std::nothrow);
+        assert(new_handler_called == 1);
+        assert(vp == 0);
+    };
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    try
+    {
+        do_test();
+    }
+    catch (...)
+    {
+        assert(false);
+    }
+#else
+    do_test();
+#endif
+}
+
+int main()
+{
+    {
+        A* ap = new(std::nothrow) A[3];
+        assert(ap);
+        assert(reinterpret_cast<std::uintptr_t>(ap) % OverAligned == 0);
+        assert(A_constructed == 3);
+        delete [] ap;
+        assert(!A_constructed);
+    }
+    {
+        test_max_alloc();
+    }
+}
Index: test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp
===================================================================
--- /dev/null
+++ test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// test operator new
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cassert>
+#include <cstdint>
+#include <limits>
+
+#include "test_macros.h"
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+int new_handler_called = 0;
+
+void new_handler()
+{
+    ++new_handler_called;
+    std::set_new_handler(0);
+}
+
+int A_constructed = 0;
+
+struct alignas(OverAligned) A
+{
+    A() { ++A_constructed;}
+    ~A() { --A_constructed;}
+};
+
+void test_throw_max_size() {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+    std::set_new_handler(new_handler);
+    try
+    {
+        void* vp = operator new[] (std::numeric_limits<std::size_t>::max(),
+                                   static_cast<std::align_val_t>(32));
+        ((void)vp);
+        assert(false);
+    }
+    catch (std::bad_alloc&)
+    {
+        assert(new_handler_called == 1);
+    }
+    catch (...)
+    {
+        assert(false);
+    }
+#endif
+}
+
+int main()
+{
+    {
+        A* ap = new A[2];
+        assert(ap);
+        assert(reinterpret_cast<std::uintptr_t>(ap) % OverAligned == 0);
+        assert(A_constructed == 2);
+        delete [] ap;
+        assert(A_constructed == 0);
+    }
+    {
+        test_throw_max_size();
+    }
+}
Index: test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp
===================================================================
--- /dev/null
+++ test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// test aligned operator delete replacement.
+
+// UNSUPPORTED: sanitizer-new-delete, c++98, c++03, c++11, c++14
+
+// Older Clang versions do not support this
+// XFAIL: clang-3, apple-clang
+
+// None of the current GCC compilers support this.
+// XFAIL: gcc-4, gcc-5, gcc-6
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+
+constexpr auto OverAligned = alignof(std::max_align_t) * 2;
+
+int unsized_delete_called = 0;
+int unsized_delete_nothrow_called = 0;
+int aligned_delete_called = 0;
+
+void reset() {
+    unsized_delete_called = 0;
+    unsized_delete_nothrow_called = 0;
+    aligned_delete_called = 0;
+}
+
+void operator delete(void* p) throw()
+{
+    ++unsized_delete_called;
+    std::free(p);
+}
+
+void operator delete(void* p, const std::nothrow_t&) throw()
+{
+    ++unsized_delete_nothrow_called;
+    std::free(p);
+}
+
+void operator delete [] (void* p, std::align_val_t a) throw()
+{
+    ++aligned_delete_called;
+    std::free(p);
+}
+
+struct alignas(OverAligned) A {};
+struct alignas(std::max_align_t) B {};
+
+int main()
+{
+    {
+        B *x = new B;
+        assert(0 == unsized_delete_called);
+        assert(0 == unsized_delete_nothrow_called);
+        assert(0 == aligned_delete_called);
+
+        delete x;
+        assert(1 == unsized_delete_called);
+        assert(0 == unsized_delete_nothrow_called);
+        assert(0 == aligned_delete_called);
+    }
+    reset();
+    {
+        A *x = new A;
+        assert(0 == unsized_delete_called);
+        assert(0 == unsized_delete_nothrow_called);
+        assert(0 == aligned_delete_called);
+
+        delete x;
+        assert(0 == unsized_delete_called);
+        assert(0 == unsized_delete_nothrow_called);
+        assert(1 == aligned_delete_called);
+    }
+}
Index: test/std/language.support/support.dynamic/align_val_t.pass.cpp
===================================================================
--- /dev/null
+++ test/std/language.support/support.dynamic/align_val_t.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// enum class align_val_t : size_t {}
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+#include <new>
+
+#include "test_macros.h"
+
+int main() {
+  {
+    static_assert(std::is_enum<std::align_val_t>::value, "");
+    static_assert(std::is_same<std::underlying_type<std::align_val_t>::type, std::size_t>::value, "");
+    static_assert(!std::is_constructible<std::align_val_t, std::size_t>::value, "");
+    static_assert(!std::is_constructible<std::size_t, std::align_val_t>::value, "");
+  }
+  {
+    constexpr auto a = std::align_val_t(0);
+    constexpr auto b = std::align_val_t(32);
+    constexpr auto c = std::align_val_t(-1);
+    static_assert(a != b, "");
+    static_assert(a == std::align_val_t(0), "");
+    static_assert(b == std::align_val_t(32), "");
+    static_assert(static_cast<std::size_t>(c) == (std::size_t)-1, "");
+  }
+}
\ No newline at end of file
Index: test/libcxx/test/config.py
===================================================================
--- test/libcxx/test/config.py
+++ test/libcxx/test/config.py
@@ -313,6 +313,9 @@
         if self.cxx.hasCompileFlag('-fsized-deallocation'):
             self.config.available_features.add('fsized-deallocation')
 
+        if self.cxx.hasCompileFlag('-faligned-allocation'):
+            self.config.available_features.add('-faligned-allocation')
+
         if self.get_lit_bool('has_libatomic', False):
             self.config.available_features.add('libatomic')
 
Index: test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp
===================================================================
--- /dev/null
+++ test/libcxx/language.support/support.dynamic/new_faligned_allocation.sh.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+// test libc++'s implementation of align_val_t, and the relevent new/delete
+// overloads in all dialects when -faligned-allocation is present.
+
+// REQUIRES: -faligned-allocation
+
+// RUN: %build -faligned-allocation
+// RUN: %run
+
+#include <new>
+#include <typeinfo>
+#include <string>
+#include <cassert>
+
+#include "test_macros.h"
+
+int main() {
+  {
+    static_assert(std::is_enum<std::align_val_t>::value, "");
+    typedef std::underlying_type<std::align_val_t>::type UT;
+    static_assert((std::is_same<UT, std::size_t>::value), "");
+  }
+  {
+    static_assert((!std::is_constructible<std::align_val_t, std::size_t>::value), "");
+#if TEST_STD_VER >= 11
+    static_assert(!std::is_constructible<std::size_t, std::align_val_t>::value, "");
+#else
+    static_assert((std::is_constructible<std::size_t, std::align_val_t>::value), "");
+#endif
+  }
+  {
+    std::align_val_t a = std::align_val_t(0);
+    std::align_val_t b = std::align_val_t(32);
+    assert(a != b);
+    assert(a == std::align_val_t(0));
+    assert(b == std::align_val_t(32));
+  }
+  {
+    void *ptr = ::operator new(1, std::align_val_t(128));
+    assert(ptr);
+    assert(reinterpret_cast<std::uintptr_t>(ptr) % 128 == 0);
+    ::operator delete(ptr, std::align_val_t(128));
+  }
+  {
+    void *ptr = ::operator new(1, std::align_val_t(128), std::nothrow);
+    assert(ptr);
+    assert(reinterpret_cast<std::uintptr_t>(ptr) % 128 == 0);
+    ::operator delete(ptr, std::align_val_t(128), std::nothrow);
+  }
+  {
+    void *ptr = ::operator new[](1, std::align_val_t(128));
+    assert(ptr);
+    assert(reinterpret_cast<std::uintptr_t>(ptr) % 128 == 0);
+    ::operator delete[](ptr, std::align_val_t(128));
+  }
+  {
+    void *ptr = ::operator new[](1, std::align_val_t(128), std::nothrow);
+    assert(ptr);
+    assert(reinterpret_cast<std::uintptr_t>(ptr) % 128 == 0);
+    ::operator delete[](ptr, std::align_val_t(128), std::nothrow);
+  }
+#ifndef TEST_HAS_NO_RTTI
+  {
+    // Check that libc++ doesn't define align_val_t in a versioning namespace.
+    // And that it mangles the same in C++03 through C++17
+    assert(typeid(std::align_val_t).name() == std::string("St11align_val_t"));
+  }
+#endif
+}
\ No newline at end of file
Index: src/new.cpp
===================================================================
--- src/new.cpp
+++ src/new.cpp
@@ -39,10 +39,7 @@
 
 _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void *
-operator new(std::size_t size)
-#if !__has_feature(cxx_noexcept)
-    throw(std::bad_alloc)
-#endif
+operator new(std::size_t size) _THROW_BAD_ALLOC
 {
     if (size == 0)
         size = 1;
@@ -65,6 +62,34 @@
 }
 
 _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+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;
+    while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0)
+    {
+        // 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 _LIBCPP_NO_EXCEPTIONS
+            throw std::bad_alloc();
+#else
+            p = nullptr; // posix_memalign doesn't initialize 'p' on failure
+            break;
+#endif
+        }
+    }
+    return p;
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void*
 operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
 {
@@ -85,16 +110,39 @@
 
 _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void*
-operator new[](size_t size)
-#if !__has_feature(cxx_noexcept)
-    throw(std::bad_alloc)
-#endif
+operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
+{
+    void* p = 0;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        p = ::operator new(size, alignment);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return p;
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void*
+operator new[](size_t size) _THROW_BAD_ALLOC
 {
     return ::operator new(size);
 }
 
 _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void*
+operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
+{
+    return ::operator new(size, alignment);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void*
 operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
 {
     void* p = 0;
@@ -113,6 +161,25 @@
 }
 
 _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void*
+operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
+{
+    void* p = 0;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    try
+    {
+#endif  // _LIBCPP_NO_EXCEPTIONS
+        p = ::operator new[](size, alignment);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+    }
+    catch (...)
+    {
+    }
+#endif  // _LIBCPP_NO_EXCEPTIONS
+    return p;
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void
 operator delete(void* ptr) _NOEXCEPT
 {
@@ -122,39 +189,82 @@
 
 _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void
+operator delete(void* ptr, std::align_val_t) _NOEXCEPT
+{
+    if (ptr)
+        ::free(ptr);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
 operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
 {
     ::operator delete(ptr);
 }
 
 _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void
+operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
+{
+    ::operator delete(ptr, alignment);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
 operator delete(void* ptr, size_t) _NOEXCEPT
 {
     ::operator delete(ptr);
 }
 
 _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void
+operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
+{
+    ::operator delete(ptr, alignment);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
 operator delete[] (void* ptr) _NOEXCEPT
 {
     ::operator delete(ptr);
 }
 
 _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void
+operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT
+{
+    ::operator delete(ptr, alignment);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
 operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT
 {
     ::operator delete[](ptr);
 }
 
 _LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
 void
+operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
+{
+    ::operator delete[](ptr, alignment);
+}
+
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
 operator delete[] (void* ptr, size_t) _NOEXCEPT
 {
     ::operator delete[](ptr);
 }
 
+_LIBCPP_WEAK _LIBCPP_NEW_DELETE_VIS
+void
+operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
+{
+    ::operator delete[](ptr, alignment);
+}
+
 #endif // !__GLIBCXX__
 
 namespace std
Index: lib/abi/x86_64-linux-gnu.abilist
===================================================================
--- lib/abi/x86_64-linux-gnu.abilist
+++ lib/abi/x86_64-linux-gnu.abilist
@@ -1,60 +1,60 @@
 {'type': 'FUNC', 'name': '__cxa_finalize@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': 'wcsnrtombs@GLIBC_2.2.5'}
 {'type': 'FUNC', 'name': '_Unwind_Resume@GCC_3.0'}
-{'type': 'FUNC', 'name': 'wctob@GLIBC_2.2.5'}
 {'type': 'FUNC', 'name': 'wcsxfrm_l@GLIBC_2.3'}
-{'type': 'FUNC', 'name': 'freelocale@GLIBC_2.3'}
-{'type': 'FUNC', 'name': 'iswblank_l@GLIBC_2.3'}
-{'type': 'FUNC', 'name': 'iswalpha_l@GLIBC_2.3'}
-{'type': 'FUNC', 'name': 'iswdigit_l@GLIBC_2.3'}
-{'type': 'FUNC', 'name': 'iswcntrl_l@GLIBC_2.3'}
-{'type': 'FUNC', 'name': 'catclose@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': 'catgets@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': 'catopen@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': '__ctype_get_mb_cur_max@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': 'btowc@GLIBC_2.2.5'}
+{'type': 'FUNC', 'name': 'vsnprintf@GLIBC_2.2.5'}
+{'type': 'FUNC', 'name': 'vasprintf@GLIBC_2.2.5'}
+{'type': 'FUNC', 'name': 'wcscoll_l@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'towupper_l@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'uselocale@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'wctob@GLIBC_2.2.5'}
+{'type': 'FUNC', 'name': 'strxfrm_l@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'wcsnrtombs@GLIBC_2.2.5'}
+{'type': 'FUNC', 'name': 'tolower_l@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'toupper_l@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'wcrtomb@GLIBC_2.2.5'}
+{'type': 'FUNC', 'name': 'vsscanf@GLIBC_2.2.5'}
+{'type': 'FUNC', 'name': 'towlower_l@GLIBC_2.3'}
 {'type': 'FUNC', 'name': '_ZSt9terminatev'}
 {'type': 'FUNC', 'name': 'strtof_l@GLIBC_2.3'}
 {'type': 'FUNC', 'name': 'setlocale@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': 'strtod_l@GLIBC_2.3'}
-{'type': 'FUNC', 'name': 'sscanf@GLIBC_2.2.5'}
 {'type': 'FUNC', 'name': 'strtold_l@GLIBC_2.3'}
-{'type': 'FUNC', 'name': 'strxfrm_l@GLIBC_2.3'}
-{'type': 'FUNC', 'name': 'mbsnrtowcs@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': 'mbsrtowcs@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': 'toupper_l@GLIBC_2.3'}
 {'type': 'FUNC', 'name': 'mbtowc@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': 'tolower_l@GLIBC_2.3'}
-{'type': 'FUNC', 'name': 'towupper_l@GLIBC_2.3'}
-{'type': 'OBJECT', 'name': '_ZTVN10__cxxabiv120__si_class_type_infoE', 'size': 0}
-{'type': 'FUNC', 'name': 'towlower_l@GLIBC_2.3'}
-{'type': 'FUNC', 'name': 'localeconv@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': 'uselocale@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'mbsrtowcs@GLIBC_2.2.5'}
+{'type': 'FUNC', 'name': 'mbsnrtowcs@GLIBC_2.2.5'}
+{'type': 'FUNC', 'name': 'strcoll_l@GLIBC_2.3'}
 {'type': 'FUNC', 'name': 'mbrtowc@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': 'wcscoll_l@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'localeconv@GLIBC_2.2.5'}
+{'type': 'FUNC', 'name': 'strftime_l@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'strtod_l@GLIBC_2.3'}
+{'type': 'OBJECT', 'name': '_ZTVN10__cxxabiv120__si_class_type_infoE', 'size': 0}
+{'type': 'FUNC', 'name': 'newlocale@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'iswxdigit_l@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'sscanf@GLIBC_2.2.5'}
 {'type': 'FUNC', 'name': 'iswprint_l@GLIBC_2.3'}
-{'type': 'FUNC', 'name': 'vsnprintf@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': 'vsscanf@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': 'iswlower_l@GLIBC_2.3'}
-{'type': 'FUNC', 'name': 'iswspace_l@GLIBC_2.3'}
-{'type': 'FUNC', 'name': 'wcrtomb@GLIBC_2.2.5'}
 {'type': 'FUNC', 'name': 'iswpunct_l@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'iswspace_l@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'catopen@GLIBC_2.2.5'}
+{'type': 'FUNC', 'name': 'catgets@GLIBC_2.2.5'}
+{'type': 'FUNC', 'name': 'iswupper_l@GLIBC_2.3'}
 {'type': 'FUNC', 'name': '__cxa_atexit@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': 'iswxdigit_l@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'iswblank_l@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'catclose@GLIBC_2.2.5'}
 {'type': 'FUNC', 'name': '__cxa_begin_catch'}
-{'type': 'FUNC', 'name': 'iswupper_l@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'btowc@GLIBC_2.2.5'}
+{'type': 'FUNC', 'name': 'iswcntrl_l@GLIBC_2.3'}
 {'type': 'FUNC', 'name': '__gxx_personality_v0'}
+{'type': 'FUNC', 'name': '__ctype_get_mb_cur_max@GLIBC_2.2.5'}
+{'type': 'FUNC', 'name': 'iswdigit_l@GLIBC_2.3'}
 {'type': 'FUNC', 'name': 'fflush@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': 'vasprintf@GLIBC_2.2.5'}
+{'type': 'FUNC', 'name': 'iswlower_l@GLIBC_2.3'}
 {'type': 'FUNC', 'name': 'fwrite@GLIBC_2.2.5'}
 {'type': 'FUNC', 'name': 'getc@GLIBC_2.2.5'}
 {'type': 'OBJECT', 'name': 'stderr@GLIBC_2.2.5', 'size': 0}
-{'type': 'FUNC', 'name': 'newlocale@GLIBC_2.3'}
+{'type': 'FUNC', 'name': 'freelocale@GLIBC_2.3'}
 {'type': 'OBJECT', 'name': 'stdin@GLIBC_2.2.5', 'size': 0}
+{'type': 'FUNC', 'name': 'iswalpha_l@GLIBC_2.3'}
 {'type': 'OBJECT', 'name': 'stdout@GLIBC_2.2.5', 'size': 0}
 {'type': 'FUNC', 'name': 'ungetc@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': 'strftime_l@GLIBC_2.3'}
-{'type': 'FUNC', 'name': 'strcoll_l@GLIBC_2.3'}
 {'type': 'FUNC', 'name': '__cxa_guard_acquire'}
 {'type': 'FUNC', 'name': '__cxa_guard_release'}
 {'type': 'FUNC', 'name': 'pthread_mutex_lock@GLIBC_2.2.5'}
@@ -89,6 +89,7 @@
 {'type': 'FUNC', 'name': '_ZSt15get_new_handlerv'}
 {'type': 'OBJECT', 'name': '_ZTISt9bad_alloc', 'size': 0}
 {'type': 'FUNC', 'name': '__cxa_end_catch'}
+{'type': 'FUNC', 'name': 'posix_memalign@GLIBC_2.2.5'}
 {'type': 'FUNC', 'name': '__errno_location@GLIBC_2.2.5'}
 {'type': 'FUNC', 'name': 'close@GLIBC_2.2.5'}
 {'type': 'FUNC', 'name': 'open@GLIBC_2.2.5'}
@@ -160,8 +161,8 @@
 {'type': 'FUNC', 'name': 'pthread_cond_timedwait@GLIBC_2.3.2'}
 {'type': 'FUNC', 'name': 'pthread_getspecific@GLIBC_2.2.5'}
 {'type': 'FUNC', 'name': 'pthread_setspecific@GLIBC_2.2.5'}
-{'type': 'FUNC', 'name': 'strtoll_l@GLIBC_2.3.3'}
 {'type': 'FUNC', 'name': 'strtoull_l@GLIBC_2.3.3'}
+{'type': 'FUNC', 'name': 'strtoll_l@GLIBC_2.3.3'}
 {'type': 'FUNC', 'name': '_ZNSt13runtime_errorD1Ev'}
 {'type': 'FUNC', 'name': '_ZNSt8bad_castC1Ev'}
 {'type': 'FUNC', 'name': '_ZNSt8bad_castD1Ev'}
@@ -319,6 +320,7 @@
 {'type': 'FUNC', 'name': '_ZThn16_NSt3__114basic_iostreamIcNS_11char_traitsIcEEED1Ev'}
 {'type': 'FUNC', 'name': '_ZNSt3__19to_stringEx'}
 {'type': 'FUNC', 'name': '_ZNKSt3__17num_getIwNS_19istreambuf_iteratorIwNS_11char_traitsIwEEEEE23__do_get_floating_pointIdEES4_S4_S4_RNS_8ios_baseERjRT_'}
+{'type': 'FUNC', 'name': '_ZdaPvSt11align_val_t'}
 {'type': 'FUNC', 'name': '_ZNSt3__110to_wstringEi'}
 {'type': 'FUNC', 'name': '_ZNSt3__19to_stringEy'}
 {'type': 'FUNC', 'name': '_ZNSt3__17__sort5IRNS_6__lessIjjEEPjEEjT0_S5_S5_S5_S5_T_'}
@@ -631,6 +633,7 @@
 {'type': 'FUNC', 'name': '_ZNKSt3__114__codecvt_utf8IDiE11do_encodingEv'}
 {'type': 'FUNC', 'name': '_ZNKSt3__18messagesIwE6do_getEliiRKNS_12basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEEE'}
 {'type': 'OBJECT', 'name': '_ZTINSt3__114error_categoryE', 'size': 16}
+{'type': 'FUNC', 'name': '_ZdlPvSt11align_val_t'}
 {'type': 'FUNC', 'name': '_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEE3getERNS_15basic_streambufIcS2_EE'}
 {'type': 'FUNC', 'name': '_ZNKSt3__115__codecvt_utf16IDsLb0EE13do_max_lengthEv'}
 {'type': 'OBJECT', 'name': '_ZTINSt3__19money_getIwNS_19istreambuf_iteratorIwNS_11char_traitsIwEEEEEE', 'size': 56}
@@ -649,6 +652,7 @@
 {'type': 'OBJECT', 'name': '_ZTSNSt3__116__narrow_to_utf8ILm32EEE', 'size': 34}
 {'type': 'FUNC', 'name': '_ZNSt3__17promiseIvEC2Ev'}
 {'type': 'FUNC', 'name': '_ZNKSt3__17num_getIcNS_19istreambuf_iteratorIcNS_11char_traitsIcEEEEE17__do_get_unsignedItEES4_S4_S4_RNS_8ios_baseERjRT_'}
+{'type': 'FUNC', 'name': '_ZnamSt11align_val_t'}
 {'type': 'FUNC', 'name': '_ZNKSt3__115__codecvt_utf16IDsLb0EE9do_lengthER11__mbstate_tPKcS5_m'}
 {'type': 'FUNC', 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC1ERKS5_'}
 {'type': 'FUNC', 'name': '_ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE4copyEPcmm'}
@@ -660,6 +664,7 @@
 {'type': 'OBJECT', 'name': '_ZTINSt3__19__num_putIcEE', 'size': 40}
 {'type': 'FUNC', 'name': '_ZNKSt3__114error_category23default_error_conditionEi'}
 {'type': 'FUNC', 'name': '_ZNSt3__16localeC2EPKc'}
+{'type': 'FUNC', 'name': '_ZdaPvmSt11align_val_t'}
 {'type': 'FUNC', 'name': '_ZNSt3__17codecvtIwc11__mbstate_tED0Ev'}
 {'type': 'OBJECT', 'name': '_ZTSNSt3__114__shared_countE', 'size': 25}
 {'type': 'FUNC', 'name': '_ZNSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE6assignERKS5_mm'}
@@ -855,6 +860,7 @@
 {'type': 'OBJECT', 'name': '_ZNSt3__110ctype_base5alnumE', 'size': 2}
 {'type': 'OBJECT', 'name': '_ZTCNSt3__110ostrstreamE0_NS_13basic_ostreamIcNS_11char_traitsIcEEEE', 'size': 80}
 {'type': 'OBJECT', 'name': '_ZTINSt3__117moneypunct_bynameIcLb0EEE', 'size': 24}
+{'type': 'FUNC', 'name': '_ZdlPvmSt11align_val_t'}
 {'type': 'FUNC', 'name': '_ZNSt3__115__thread_struct27__make_ready_at_thread_exitEPNS_17__assoc_sub_stateE'}
 {'type': 'FUNC', 'name': '_ZNKSt3__120__codecvt_utf8_utf16IDiE6do_outER11__mbstate_tPKDiS5_RS5_PcS7_RS7_'}
 {'type': 'FUNC', 'name': '_ZNSt3__112system_errorD0Ev'}
@@ -1114,6 +1120,7 @@
 {'type': 'FUNC', 'name': '_ZNSt3__112__next_primeEm'}
 {'type': 'FUNC', 'name': '_ZNSt3__111__call_onceERVmPvPFvS2_E'}
 {'type': 'FUNC', 'name': '_ZNSt3__110__time_getC1EPKc'}
+{'type': 'FUNC', 'name': '_ZdlPvSt11align_val_tRKSt9nothrow_t'}
 {'type': 'OBJECT', 'name': '_ZNSt3__16chrono12system_clock9is_steadyE', 'size': 1}
 {'type': 'FUNC', 'name': '_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEErsERs'}
 {'type': 'FUNC', 'name': '_ZNSt3__113basic_istreamIcNS_11char_traitsIcEEErsERt'}
@@ -1227,6 +1234,7 @@
 {'type': 'FUNC', 'name': '_ZNSt3__115numpunct_bynameIwEC2EPKcm'}
 {'type': 'FUNC', 'name': '_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryD2Ev'}
 {'type': 'FUNC', 'name': '_ZNSt3__15mutexD1Ev'}
+{'type': 'FUNC', 'name': '_ZnwmSt11align_val_tRKSt9nothrow_t'}
 {'type': 'FUNC', 'name': '_ZNSt3__115__thread_structC2Ev'}
 {'type': 'FUNC', 'name': '_ZNSt3__120__codecvt_utf8_utf16IDsED0Ev'}
 {'type': 'OBJECT', 'name': '_ZTVNSt3__115basic_streambufIwNS_11char_traitsIwEEEE', 'size': 128}
@@ -1313,6 +1321,7 @@
 {'type': 'FUNC', 'name': '_ZNSt3__113basic_istreamIwNS_11char_traitsIwEEErsEPNS_15basic_streambufIwS2_EE'}
 {'type': 'OBJECT', 'name': '_ZTINSt3__16locale5facetE', 'size': 24}
 {'type': 'FUNC', 'name': '_ZNSt13exception_ptrD2Ev'}
+{'type': 'FUNC', 'name': '_ZnamSt11align_val_tRKSt9nothrow_t'}
 {'type': 'OBJECT', 'name': '_ZTSNSt3__115basic_streambufIcNS_11char_traitsIcEEEE', 'size': 49}
 {'type': 'FUNC', 'name': '_ZNSt3__15mutexD2Ev'}
 {'type': 'FUNC', 'name': '_ZNSt3__113random_deviceD1Ev'}
@@ -1478,6 +1487,7 @@
 {'type': 'FUNC', 'name': '_ZNKSt3__112ctype_bynameIwE10do_tolowerEPwPKw'}
 {'type': 'OBJECT', 'name': '_ZTINSt3__112strstreambufE', 'size': 24}
 {'type': 'FUNC', 'name': '_ZNKSt3__112basic_stringIwNS_11char_traitsIwEENS_9allocatorIwEEE16find_last_not_ofEPKwmm'}
+{'type': 'FUNC', 'name': '_ZdaPvSt11align_val_tRKSt9nothrow_t'}
 {'type': 'FUNC', 'name': '_ZNSt3__119__shared_mutex_base6unlockEv'}
 {'type': 'FUNC', 'name': '_ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE4swapERS3_'}
 {'type': 'FUNC', 'name': '_ZNSt3__114codecvt_bynameIDic11__mbstate_tED0Ev'}
@@ -1734,6 +1744,7 @@
 {'type': 'FUNC', 'name': '_ZNSt3__115basic_streambufIwNS_11char_traitsIwEEEC1Ev'}
 {'type': 'FUNC', 'name': '_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6assignERKS5_mm'}
 {'type': 'FUNC', 'name': '_ZNKSt3__112ctype_bynameIcE10do_toupperEc'}
+{'type': 'FUNC', 'name': '_ZnwmSt11align_val_t'}
 {'type': 'FUNC', 'name': '_ZNKSt3__18time_getIcNS_19istreambuf_iteratorIcNS_11char_traitsIcEEEEE16do_get_monthnameES4_S4_RNS_8ios_baseERjP2tm'}
 {'type': 'FUNC', 'name': '_ZNSt3__116__narrow_to_utf8ILm16EED1Ev'}
 {'type': 'OBJECT', 'name': '_ZTSNSt3__19__num_getIwEE', 'size': 22}
Index: lib/abi/CHANGELOG.TXT
===================================================================
--- lib/abi/CHANGELOG.TXT
+++ lib/abi/CHANGELOG.TXT
@@ -16,6 +16,22 @@
 Version 4.0
 -----------
 
+* rTBD - Implement C++17 aligned allocation in <new>
+
+  x86_64-linux-gnu
+  ----------------
+  Symbol added: posix_memalign@GLIBC_2.2.5
+  Symbol added: _ZdaPvSt11align_val_t
+  Symbol added: _ZdlPvSt11align_val_t
+  Symbol added: _ZnamSt11align_val_t
+  Symbol added: _ZdaPvmSt11align_val_t
+  Symbol added: _ZdlPvmSt11align_val_t
+  Symbol added: _ZdlPvSt11align_val_tRKSt9nothrow_t
+  Symbol added: _ZnwmSt11align_val_tRKSt9nothrow_t
+  Symbol added: _ZnamSt11align_val_tRKSt9nothrow_t
+  Symbol added: _ZdaPvSt11align_val_tRKSt9nothrow_t
+  Symbol added: _ZnwmSt11align_val_t
+
 * r283980 - Implement C++17 <optional>
 
   x86_64-linux-gnu
Index: include/new
===================================================================
--- include/new
+++ include/new
@@ -27,18 +27,19 @@
     virtual const char* what() const noexcept;
 };
 
-class bad_array_length : public bad_alloc // C++14
+class bad_array_length : public bad_alloc // FIXME: Not part of C++
 {
 public:
     bad_array_length() noexcept;
 };
 
-class bad_array_new_length : public bad_alloc
+class bad_array_new_length : public bad_alloc // C++14
 {
 public:
     bad_array_new_length() noexcept;
 };
 
+enum class align_val_t : size_t {}; // C++17
 struct nothrow_t {};
 extern const nothrow_t nothrow;
 typedef void (*new_handler)();
@@ -48,16 +49,34 @@
 }  // std
 
 void* operator new(std::size_t size);                                   // replaceable
+void* operator new(std::size_t size, std::align_val_t alignment);       // replaceable, C++17
 void* operator new(std::size_t size, const std::nothrow_t&) noexcept;   // replaceable
+void* operator new(std::size_t size, std::align_val_t alignment,
+                   const std::nothrow_t&) noexcept;                     // replaceable, C++17
 void  operator delete(void* ptr) noexcept;                              // replaceable
 void  operator delete(void* ptr, std::size_t size) noexcept;            // replaceable, C++14
+void  operator delete(void* ptr, std::align_val_t alignment) noexcept;  // replaceable, C++17
+void  operator delete(void* ptr, std::size_t size,
+                      std::align_val_t alignment) noexcept;             // replaceable, C++17
 void  operator delete(void* ptr, const std::nothrow_t&) noexcept;       // replaceable
+void  operator delete(void* ptr, std:align_val_t alignment,
+                      const std::nothrow_t&) noexcept;                  // replaceable, C++17
 
 void* operator new[](std::size_t size);                                 // replaceable
+void* operator new[](std::size_t size,
+                     std::align_val_t alignment) noexcept;              // replaceable, C++17
 void* operator new[](std::size_t size, const std::nothrow_t&) noexcept; // replaceable
+void* operator new[](std::size_t size, std::align_val_t alignment,
+                     const std::nothrow_t&) noexcept;                   // replaceable, C++17
 void  operator delete[](void* ptr) noexcept;                            // replaceable
 void  operator delete[](void* ptr, std::size_t size) noexcept;          // replaceable, C++14
+void  operator delete[](void* ptr,
+                        std::align_val_t alignment) noexcept;           // replaceable, C++17
+void  operator delete[](void* ptr, std::size_t size,
+                        std::align_val_t alignment) noexcept;           // replaceable, C++17
 void  operator delete[](void* ptr, const std::nothrow_t&) noexcept;     // replaceable
+void  operator delete[](void* ptr, std::align_val_t alignment,
+                        const std::nothrow_t&) noexcept;                // replaceable, C++17
 
 void* operator new  (std::size_t size, void* ptr) noexcept;
 void* operator new[](std::size_t size, void* ptr) noexcept;
@@ -79,6 +98,16 @@
 #pragma GCC system_header
 #endif
 
+#if !(defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \
+    (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309))
+# define _LIBCPP_HAS_NO_SIZED_DEALLOCATION
+#endif
+
+#if !(defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER > 14 || \
+    (defined(__cpp_aligned_new) && __cpp_aligned_new >= 201606))
+# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+#endif
+
 namespace std  // purposefully not using versioning namespace
 {
 
@@ -117,6 +146,14 @@
 
 #endif  // defined(_LIBCPP_BUILDING_NEW) || (_LIBCPP_STD_VER > 11)
 
+#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+#ifndef _LIBCPP_CXX03_LANG
+enum class _LIBCPP_ENUM_VIS align_val_t : size_t { };
+#else
+enum align_val_t { __zero = 0, __max = (size_t)-1 };
+#endif
+#endif
+
 struct _LIBCPP_TYPE_VIS nothrow_t {};
 extern _LIBCPP_FUNC_VIS const nothrow_t nothrow;
 typedef void (*new_handler)();
@@ -131,32 +168,46 @@
 # define _LIBCPP_NEW_DELETE_VIS _LIBCPP_FUNC_VIS
 #endif
 
-_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz)
 #if !__has_feature(cxx_noexcept)
-    throw(std::bad_alloc)
+#define _THROW_BAD_ALLOC throw(std::bad_alloc)
+#else
+#define _THROW_BAD_ALLOC
 #endif
-;
+
+_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz) _THROW_BAD_ALLOC;
 _LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
 _LIBCPP_NEW_DELETE_VIS void  operator delete(void* __p) _NOEXCEPT;
 _LIBCPP_NEW_DELETE_VIS void  operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT;
-#if defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \
-    (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309)
+#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
 _LIBCPP_NEW_DELETE_VIS void  operator delete(void* __p, std::size_t __sz) _NOEXCEPT;
 #endif
 
-_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz)
-#if !__has_feature(cxx_noexcept)
-    throw(std::bad_alloc)
-#endif
-;
+_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz) _THROW_BAD_ALLOC;
 _LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
 _LIBCPP_NEW_DELETE_VIS void  operator delete[](void* __p) _NOEXCEPT;
 _LIBCPP_NEW_DELETE_VIS void  operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT;
-#if defined(_LIBCPP_BUILDING_NEW) || _LIBCPP_STD_VER >= 14 || \
-    (defined(__cpp_sized_deallocation) && __cpp_sized_deallocation >= 201309)
+#ifdef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
 _LIBCPP_NEW_DELETE_VIS void  operator delete[](void* __p, std::size_t __sz) _NOEXCEPT;
 #endif
 
+#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
+_LIBCPP_NEW_DELETE_VIS void* operator new(std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
+_LIBCPP_NEW_DELETE_VIS void  operator delete(void* __p, std::align_val_t) _NOEXCEPT;
+_LIBCPP_NEW_DELETE_VIS void  operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
+#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
+_LIBCPP_NEW_DELETE_VIS void  operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
+#endif
+
+_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
+_LIBCPP_NEW_DELETE_VIS void* operator new[](std::size_t __sz, std::align_val_t, const std::nothrow_t&) _NOEXCEPT _NOALIAS;
+_LIBCPP_NEW_DELETE_VIS void  operator delete[](void* __p, std::align_val_t) _NOEXCEPT;
+_LIBCPP_NEW_DELETE_VIS void  operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
+#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
+_LIBCPP_NEW_DELETE_VIS void  operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
+#endif
+#endif
+
 inline _LIBCPP_INLINE_VISIBILITY void* operator new  (std::size_t, void* __p) _NOEXCEPT {return __p;}
 inline _LIBCPP_INLINE_VISIBILITY void* operator new[](std::size_t, void* __p) _NOEXCEPT {return __p;}
 inline _LIBCPP_INLINE_VISIBILITY void  operator delete  (void*, void*) _NOEXCEPT {}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to