[libcxx-commits] [libcxx] 54e3fc3 - [libc++] Complete refactor of tests for operator new

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Tue May 23 21:49:26 PDT 2023


Author: Louis Dionne
Date: 2023-05-23T21:48:49-07:00
New Revision: 54e3fc3563b9eead46dd5f7ee3e06fec75b242a7

URL: https://github.com/llvm/llvm-project/commit/54e3fc3563b9eead46dd5f7ee3e06fec75b242a7
DIFF: https://github.com/llvm/llvm-project/commit/54e3fc3563b9eead46dd5f7ee3e06fec75b242a7.diff

LOG: [libc++] Complete refactor of tests for operator new

I stumbled upon the `operator new` and `operator new[]` tests while
investigating an issue with `operator new` when exceptions are disabled,
and I realized that our test coverage was incomplete. This patch refactors
all the `operator new` and `operator new[]` tests to add consistency and
better coverage for scenarios in which it should be possible to override
an operator indirectly by defining another one (for example new(size_t, nothrow)
should use new(size_t) if it has been provided).

This is intended to be a NFC setting up the terrain for some refactoring
work and bug fix in operator new.

Differential Revision: https://reviews.llvm.org/D150408

Added: 
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.replace.indirect.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.indirect.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.indirect.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.indirect.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/nodiscard.verify.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size.replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align.replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.indirect.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.replace.indirect.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/nodiscard.verify.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/types.h

Modified: 
    libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
    libcxx/test/libcxx/language.support/support.dynamic/new_faligned_allocation.pass.cpp
    libcxx/test/std/language.support/support.dynamic/align_val_t.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp
    libcxx/test/support/test_macros.h

Removed: 
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size.verify.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align.verify.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align_nothrow.verify.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_nothrow.verify.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size.verify.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align.verify.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align_nothrow.verify.cpp
    libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_nothrow.verify.cpp


################################################################################
diff  --git a/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp b/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
index 9acaa4a60d619..12c73e3e3b32c 100644
--- a/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
+++ b/libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp
@@ -13,7 +13,7 @@
 // using those with -faligned-allocation results in a link error.
 // XFAIL: availability-aligned_allocation-missing
 
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
 // nor does the dynamic library shipped with z/OS.
 // UNSUPPORTED: target={{.+}}-zos{{.*}}
 

diff  --git a/libcxx/test/libcxx/language.support/support.dynamic/new_faligned_allocation.pass.cpp b/libcxx/test/libcxx/language.support/support.dynamic/new_faligned_allocation.pass.cpp
index 8d766acfcfc1e..b6d3b5c1eb803 100644
--- a/libcxx/test/libcxx/language.support/support.dynamic/new_faligned_allocation.pass.cpp
+++ b/libcxx/test/libcxx/language.support/support.dynamic/new_faligned_allocation.pass.cpp
@@ -13,7 +13,7 @@
 // using those with -faligned-allocation results in a link error.
 // XFAIL: availability-aligned_allocation-missing
 
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
 // nor does the dynamic library shipped with z/OS.
 // UNSUPPORTED: target={{.+}}-zos{{.*}}
 

diff  --git a/libcxx/test/std/language.support/support.dynamic/align_val_t.pass.cpp b/libcxx/test/std/language.support/support.dynamic/align_val_t.pass.cpp
index a592fbae3c37e..c1f9f2f6cc6fe 100644
--- a/libcxx/test/std/language.support/support.dynamic/align_val_t.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/align_val_t.pass.cpp
@@ -10,7 +10,7 @@
 
 // UNSUPPORTED: c++03, c++11, c++14
 
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
 // nor does the dynamic library shipped with z/OS.
 // UNSUPPORTED: target={{.+}}-zos{{.*}}
 

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp
index 3dd7855e4adfd..33d5225586b96 100644
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/delete_align_val_t_replace.pass.cpp
@@ -10,7 +10,7 @@
 
 // UNSUPPORTED: sanitizer-new-delete, c++03, c++11, c++14
 
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
 // nor does the dynamic library shipped with z/OS.
 // UNSUPPORTED: target={{.+}}-zos{{.*}}
 

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.pass.cpp
new file mode 100644
index 0000000000000..437d064307735
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new[](std::size_t);
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+#include "../types.h"
+
+int new_handler_called = 0;
+
+void my_new_handler() {
+    ++new_handler_called;
+    std::set_new_handler(nullptr);
+}
+
+int main(int, char**) {
+    // Test that we can call the function directly
+    {
+        void* x = operator new[](10);
+        assert(x != nullptr);
+        operator delete[](x);
+    }
+
+    // Test that the new handler is called if allocation fails
+    {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+        std::set_new_handler(my_new_handler);
+        try {
+            void* x = operator new[] (std::numeric_limits<std::size_t>::max());
+            (void)x;
+            assert(false);
+        }
+        catch (std::bad_alloc const&) {
+            assert(new_handler_called == 1);
+        } catch (...) {
+            assert(false);
+        }
+#endif
+    }
+
+    // Test that a new expression constructs the right objects
+    // and a delete expression deletes them. The brace-init requires C++11.
+    {
+#if TEST_STD_VER >= 11
+        LifetimeInformation infos[3];
+        TrackLifetime* x = new TrackLifetime[3]{infos[0], infos[1], infos[2]};
+        assert(x != nullptr);
+
+        void* addresses[3] = {&x[0], &x[1], &x[2]};
+        assert(infos[0].address_constructed == addresses[0]);
+        assert(infos[1].address_constructed == addresses[1]);
+        assert(infos[2].address_constructed == addresses[2]);
+
+        delete[] x;
+        assert(infos[0].address_destroyed == addresses[0]);
+        assert(infos[1].address_destroyed == addresses[1]);
+        assert(infos[2].address_destroyed == addresses[2]);
+#endif
+    }
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.replace.indirect.pass.cpp
similarity index 63%
rename from libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp
rename to libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.replace.indirect.pass.cpp
index 46874433ffe94..172b6cc2f2944 100644
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_replace.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.replace.indirect.pass.cpp
@@ -6,7 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test operator new[] replacement by replacing only operator new
+// void* operator new[](std::size_t);
+
+// Test that we can replace the operator by replacing the `operator new(std::size_t)` (the non-array version).
 
 // UNSUPPORTED: sanitizer-new-delete
 // XFAIL: libcpp-no-vcruntime
@@ -21,41 +23,29 @@
 #include "test_macros.h"
 
 int new_called = 0;
+int delete_called = 0;
 
-void* operator new(std::size_t s) TEST_THROW_SPEC(std::bad_alloc)
-{
+TEST_WORKAROUND_BUG_109234844_WEAK
+void* operator new(std::size_t s) TEST_THROW_SPEC(std::bad_alloc) {
     ++new_called;
     void* ret = std::malloc(s);
     if (!ret) std::abort(); // placate MSVC's unchecked malloc warning
     return  ret;
 }
 
-void  operator delete(void* p) TEST_NOEXCEPT
-{
-    --new_called;
+void operator delete(void* p) TEST_NOEXCEPT {
+    ++delete_called;
     std::free(p);
 }
 
-int A_constructed = 0;
-
-struct A
-{
-    A() {++A_constructed;}
-    ~A() {--A_constructed;}
-};
-
-int main(int, char**)
-{
-    new_called = 0;
-    A *ap = new A[3];
-    DoNotOptimize(ap);
-    assert(ap);
-    assert(A_constructed == 3);
+int main(int, char**) {
+    new_called = delete_called = 0;
+    int* x = new int[3];
+    assert(x != nullptr);
     ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1);
-    delete [] ap;
-    DoNotOptimize(ap);
-    assert(A_constructed == 0);
-    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 0);
 
-  return 0;
+    delete[] x;
+    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(delete_called == 1);
+
+    return 0;
 }

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.replace.pass.cpp
similarity index 53%
rename from libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp
rename to libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.replace.pass.cpp
index 267e1d554d069..e352c00b4d0af 100644
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow_replace.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size.replace.pass.cpp
@@ -6,11 +6,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test operator new [] nothrow by replacing only operator new
+// void* operator new[](std::size_t);
+
+// Test that we can replace the operator by defining our own.
 
 // UNSUPPORTED: sanitizer-new-delete
 // XFAIL: libcpp-no-vcruntime
-// XFAIL: LIBCXX-AIX-FIXME
 
 #include <new>
 #include <cstddef>
@@ -21,41 +22,28 @@
 #include "test_macros.h"
 
 int new_called = 0;
+int delete_called = 0;
 
-void* operator new(std::size_t s) TEST_THROW_SPEC(std::bad_alloc)
-{
+void* operator new[](std::size_t s) TEST_THROW_SPEC(std::bad_alloc) {
     ++new_called;
     void* ret = std::malloc(s);
     if (!ret) std::abort(); // placate MSVC's unchecked malloc warning
     return  ret;
 }
 
-void  operator delete(void* p) TEST_NOEXCEPT
-{
-    --new_called;
+void operator delete[](void* p) TEST_NOEXCEPT {
+    ++delete_called;
     std::free(p);
 }
 
-int A_constructed = 0;
-
-struct A
-{
-    A() {++A_constructed;}
-    ~A() {--A_constructed;}
-};
-
-int main(int, char**)
-{
-    new_called = 0;
-    A *ap = new (std::nothrow) A[3];
-    DoNotOptimize(ap);
-    assert(ap);
-    assert(A_constructed == 3);
-    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called);
-    delete [] ap;
-    DoNotOptimize(ap);
-    assert(A_constructed == 0);
-    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(!new_called);
-
-  return 0;
+int main(int, char**) {
+    new_called = delete_called = 0;
+    int* x = new int[3];
+    assert(x != nullptr);
+    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1);
+
+    delete[] x;
+    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(delete_called == 1);
+
+    return 0;
 }

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.pass.cpp
new file mode 100644
index 0000000000000..b7bfee9f58609
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new[](std::size_t, std::align_val_t);
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: sanitizer-new-delete
+
+// We get availability markup errors when aligned allocation is missing
+// XFAIL: availability-aligned_allocation-missing
+
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
+// nor does the dynamic library shipped with z/OS.
+// UNSUPPORTED: target={{.+}}-zos{{.*}}
+
+#include <new>
+#include <cstddef>
+#include <cassert>
+#include <cstdint>
+#include <limits>
+
+#include "test_macros.h"
+#include "../types.h"
+
+int new_handler_called = 0;
+
+void my_new_handler() {
+    ++new_handler_called;
+    std::set_new_handler(nullptr);
+}
+
+int main(int, char**) {
+    // Test that we can call the function directly
+    {
+        void* x = operator new[](10, static_cast<std::align_val_t>(64));
+        assert(x != nullptr);
+        assert(reinterpret_cast<std::uintptr_t>(x) % 64 == 0);
+        operator delete[](x, static_cast<std::align_val_t>(64));
+    }
+
+    // Test that the new handler is called if allocation fails
+    {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+        std::set_new_handler(my_new_handler);
+        try {
+            void* x = operator new[] (std::numeric_limits<std::size_t>::max(),
+                                      static_cast<std::align_val_t>(32));
+            (void)x;
+            assert(false);
+        } catch (std::bad_alloc const&) {
+            assert(new_handler_called == 1);
+        } catch (...) {
+            assert(false);
+        }
+#endif
+    }
+
+    // Test that a new expression constructs the right object
+    // and a delete expression deletes it
+    {
+        LifetimeInformation infos[3];
+        TrackLifetimeOverAligned* x = new TrackLifetimeOverAligned[3]{infos[0], infos[1], infos[2]};
+        assert(x != nullptr);
+        assert(reinterpret_cast<std::uintptr_t>(x) % alignof(TrackLifetimeOverAligned) == 0);
+
+        void* addresses[3] = {&x[0], &x[1], &x[2]};
+        assert(infos[0].address_constructed == addresses[0]);
+        assert(infos[1].address_constructed == addresses[1]);
+        assert(infos[2].address_constructed == addresses[2]);
+
+        delete[] x;
+        assert(infos[0].address_destroyed == addresses[0]);
+        assert(infos[1].address_destroyed == addresses[1]);
+        assert(infos[2].address_destroyed == addresses[2]);
+    }
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.indirect.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.indirect.pass.cpp
new file mode 100644
index 0000000000000..283bc35315d13
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.indirect.pass.cpp
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new[](std::size_t, std::align_val_t);
+
+// Test that we can replace the operator by replacing `operator new(std::size_t, std::align_val_t)` (the non-array version).
+
+// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: sanitizer-new-delete
+
+// XFAIL: LIBCXX-AIX-FIXME
+
+// We get availability markup errors when aligned allocation is missing
+// XFAIL: availability-aligned_allocation-missing
+
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
+// nor does the dynamic library shipped with z/OS.
+// UNSUPPORTED: target={{.+}}-zos{{.*}}
+
+// TODO: Investigate why this fails on MinGW-shared
+// UNSUPPORTED: target={{.+}}-windows-gnu
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cstdint>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+#include "../types.h"
+
+int new_called = 0;
+int delete_called = 0;
+
+alignas(OverAligned) char DummyData[alignof(OverAligned) * 3];
+
+TEST_WORKAROUND_BUG_109234844_WEAK
+void* operator new(std::size_t s, std::align_val_t a) {
+    assert(s <= sizeof(DummyData));
+    assert(static_cast<std::size_t>(a) == alignof(OverAligned));
+    ++new_called;
+    return DummyData;
+}
+
+void operator delete(void*, std::align_val_t) noexcept {
+    ++delete_called;
+    // nothing to delete, we didn't actually allocate in `operator new`
+}
+
+int main(int, char**) {
+    // Test with an overaligned type
+    {
+        new_called = delete_called = 0;
+        OverAligned* x = new OverAligned[3];
+        assert(static_cast<void*>(x) == DummyData);
+        assert(new_called == 1);
+
+        delete[] x;
+        assert(delete_called == 1);
+    }
+
+    // Test with a type that is right on the verge of being overaligned
+    {
+        new_called = delete_called = 0;
+        MaxAligned* x = new MaxAligned[3];
+        assert(x != nullptr);
+        assert(new_called == 0);
+
+        delete[] x;
+        assert(delete_called == 0);
+    }
+
+    // Test with a type that is clearly not overaligned
+    {
+        new_called = delete_called = 0;
+        int* x = new int[3];
+        assert(x != nullptr);
+        assert(new_called == 0);
+
+        delete[] x;
+        assert(delete_called == 0);
+    }
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.pass.cpp
new file mode 100644
index 0000000000000..4619a71629a7b
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.replace.pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new[](std::size_t, std::align_val_t);
+
+// Test that we can replace the operator by defining our own.
+
+// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: sanitizer-new-delete
+
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
+// nor does the dynamic library shipped with z/OS.
+// UNSUPPORTED: target={{.+}}-zos{{.*}}
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cstdint>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+#include "../types.h"
+
+int new_called = 0;
+int delete_called = 0;
+
+alignas(OverAligned) char DummyData[alignof(OverAligned) * 3];
+
+void* operator new[](std::size_t s, std::align_val_t a) {
+    assert(s <= sizeof(DummyData));
+    assert(static_cast<std::size_t>(a) == alignof(OverAligned));
+    ++new_called;
+    return DummyData;
+}
+
+void operator delete[](void*, std::align_val_t) noexcept {
+    ++delete_called;
+    // nothing to delete, we didn't actually allocate in `operator new`
+}
+
+int main(int, char**) {
+    // Test with an overaligned type
+    {
+        new_called = delete_called = 0;
+        OverAligned* x = new OverAligned[3];
+        assert(static_cast<void*>(x) == DummyData);
+        assert(new_called == 1);
+
+        delete[] x;
+        assert(delete_called == 1);
+    }
+
+    // Test with a type that is right on the verge of being overaligned
+    {
+        new_called = delete_called = 0;
+        MaxAligned* x = new MaxAligned[3];
+        assert(x != nullptr);
+        assert(new_called == 0);
+
+        delete[] x;
+        assert(delete_called == 0);
+    }
+
+    // Test with a type that is clearly not overaligned
+    {
+        new_called = delete_called = 0;
+        int* x = new int[3];
+        assert(x != nullptr);
+        assert(new_called == 0);
+
+        delete[] x;
+        assert(delete_called == 0);
+    }
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.pass.cpp
new file mode 100644
index 0000000000000..ca1e529d6b74f
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.pass.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new[](std::size_t, std::align_val_t, std::nothrow_t const&);
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: sanitizer-new-delete
+
+// We get availability markup errors when aligned allocation is missing
+// XFAIL: availability-aligned_allocation-missing
+
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
+// nor does the dynamic library shipped with z/OS.
+// UNSUPPORTED: target={{.+}}-zos{{.*}}
+
+#include <new>
+#include <cstddef>
+#include <cstdint>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+#include "../types.h"
+
+int new_handler_called = 0;
+
+void my_new_handler() {
+    ++new_handler_called;
+    std::set_new_handler(nullptr);
+}
+
+int main(int, char**) {
+    // Test that we can call the function directly
+    {
+        void* x = operator new[](10, static_cast<std::align_val_t>(64), std::nothrow);
+        assert(x != nullptr);
+        assert(reinterpret_cast<std::uintptr_t>(x) % 64 == 0);
+        operator delete[](x, static_cast<std::align_val_t>(64), std::nothrow);
+    }
+
+    // Test that the new handler is called and we return nullptr if allocation fails
+    {
+        std::set_new_handler(my_new_handler);
+        void* x = operator new[](std::numeric_limits<std::size_t>::max(),
+                                 static_cast<std::align_val_t>(32), std::nothrow);
+        assert(new_handler_called == 1);
+        assert(x == nullptr);
+    }
+
+    // Test that a new expression constructs the right object
+    // and a delete expression deletes it
+    {
+        LifetimeInformation infos[3];
+        TrackLifetimeOverAligned* x = new (std::nothrow) TrackLifetimeOverAligned[3]{infos[0], infos[1], infos[2]};
+        assert(x != nullptr);
+        assert(reinterpret_cast<std::uintptr_t>(x) % alignof(TrackLifetimeOverAligned) == 0);
+
+        void* addresses[3] = {&x[0], &x[1], &x[2]};
+        assert(infos[0].address_constructed == addresses[0]);
+        assert(infos[1].address_constructed == addresses[1]);
+        assert(infos[2].address_constructed == addresses[2]);
+
+        delete[] x;
+        assert(infos[0].address_destroyed == addresses[0]);
+        assert(infos[1].address_destroyed == addresses[1]);
+        assert(infos[2].address_destroyed == addresses[2]);
+    }
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.indirect.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.indirect.pass.cpp
new file mode 100644
index 0000000000000..52f207e62e09b
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.indirect.pass.cpp
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new[](std::size_t, std::align_val_t, std::nothrow_t const&);
+
+// Test that we can replace the operator by replacing `operator new[](std::size_t, std::align_val_t)`
+// (the throwing version).
+
+// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: sanitizer-new-delete
+
+// XFAIL: LIBCXX-AIX-FIXME
+
+// We get availability markup errors when aligned allocation is missing
+// XFAIL: availability-aligned_allocation-missing
+
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
+// nor does the dynamic library shipped with z/OS.
+// UNSUPPORTED: target={{.+}}-zos{{.*}}
+
+// TODO: Investigate why this fails on MinGW-shared
+// UNSUPPORTED: target={{.+}}-windows-gnu
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+#include "../types.h"
+
+int new_called = 0;
+int delete_called = 0;
+
+alignas(OverAligned) char DummyData[alignof(OverAligned) * 3];
+
+TEST_WORKAROUND_BUG_109234844_WEAK
+void* operator new[](std::size_t s, std::align_val_t a) {
+    assert(s <= sizeof(DummyData));
+    assert(static_cast<std::size_t>(a) == alignof(OverAligned));
+    ++new_called;
+    return DummyData;
+}
+
+void operator delete[](void*, std::align_val_t) noexcept {
+    ++delete_called;
+    // nothing to delete, we didn't actually allocate in `operator new`
+}
+
+int main(int, char**) {
+    // Test with an overaligned type
+    {
+        new_called = delete_called = 0;
+        OverAligned* x = new (std::nothrow) OverAligned[3];
+        assert(static_cast<void*>(x) == DummyData);
+        ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1);
+
+        delete[] x;
+        ASSERT_WITH_OPERATOR_NEW_FALLBACKS(delete_called == 1);
+    }
+
+    // Test with a type that is right on the verge of being overaligned
+    {
+        new_called = delete_called = 0;
+        MaxAligned* x = new (std::nothrow) MaxAligned[3];
+        assert(x != nullptr);
+        assert(new_called == 0);
+
+        delete[] x;
+        assert(delete_called == 0);
+    }
+
+    // Test with a type that is clearly not overaligned
+    {
+        new_called = delete_called = 0;
+        int* x = new (std::nothrow) int[3];
+        assert(x != nullptr);
+        assert(new_called == 0);
+
+        delete[] x;
+        assert(delete_called == 0);
+    }
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.pass.cpp
new file mode 100644
index 0000000000000..9a830e0e82990
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.replace.pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new[](std::size_t, std::align_val_t, std::nothrow_t const&);
+
+// Test that we can replace the operator by defining our own.
+
+// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: sanitizer-new-delete
+
+// We get availability markup errors when aligned allocation is missing
+// XFAIL: availability-aligned_allocation-missing
+
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
+// nor does the dynamic library shipped with z/OS.
+// UNSUPPORTED: target={{.+}}-zos{{.*}}
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+#include "../types.h"
+
+int new_nothrow_called = 0;
+int delete_called = 0;
+
+alignas(OverAligned) char DummyData[alignof(OverAligned) * 3];
+
+TEST_WORKAROUND_BUG_109234844_WEAK
+void* operator new[](std::size_t s, std::align_val_t a, std::nothrow_t const&) noexcept {
+    assert(s <= sizeof(DummyData));
+    assert(static_cast<std::size_t>(a) == alignof(OverAligned));
+    ++new_nothrow_called;
+    return DummyData;
+}
+
+void operator delete[](void*, std::align_val_t) noexcept {
+    ++delete_called;
+    // nothing to delete, we didn't actually allocate in `operator new`
+}
+
+int main(int, char**) {
+    // Test with an overaligned type
+    {
+        new_nothrow_called = delete_called = 0;
+        OverAligned* x = new (std::nothrow) OverAligned[3];
+        assert(static_cast<void*>(x) == DummyData);
+        ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_nothrow_called == 1);
+
+        delete[] x;
+        ASSERT_WITH_OPERATOR_NEW_FALLBACKS(delete_called == 1);
+    }
+
+    // Test with a type that is right on the verge of being overaligned
+    {
+        new_nothrow_called = delete_called = 0;
+        MaxAligned* x = new (std::nothrow) MaxAligned[3];
+        assert(x != nullptr);
+        assert(new_nothrow_called == 0);
+
+        delete[] x;
+        assert(delete_called == 0);
+    }
+
+    // Test with a type that is clearly not overaligned
+    {
+        new_nothrow_called = delete_called = 0;
+        int* x = new (std::nothrow) int[3];
+        assert(x != nullptr);
+        assert(new_nothrow_called == 0);
+
+        delete[] x;
+        assert(delete_called == 0);
+    }
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.pass.cpp
new file mode 100644
index 0000000000000..c42453abb04dc
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new[](std::size_t, std::nothrow_t const&);
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+#include "../types.h"
+
+int new_handler_called = 0;
+
+void my_new_handler() {
+    ++new_handler_called;
+    std::set_new_handler(nullptr);
+}
+
+int main(int, char**) {
+    // Test that we can call the function directly
+    {
+        void* x = operator new[](10, std::nothrow);
+        assert(x != nullptr);
+        operator delete[](x, std::nothrow);
+    }
+
+    // Test that the new handler is called and we return nullptr if allocation fails
+    {
+        std::set_new_handler(my_new_handler);
+        void* x = operator new[](std::numeric_limits<std::size_t>::max(), std::nothrow);
+        assert(new_handler_called == 1);
+        assert(x == nullptr);
+    }
+
+    // Test that a new expression constructs the right objects
+    // and a delete expression deletes them. The brace-init requires C++11.
+    {
+#if TEST_STD_VER >= 11
+        LifetimeInformation infos[3];
+        TrackLifetime* x = new (std::nothrow) TrackLifetime[3]{infos[0], infos[1], infos[2]};
+        assert(x != nullptr);
+
+        void* addresses[3] = {&x[0], &x[1], &x[2]};
+        assert(infos[0].address_constructed == addresses[0]);
+        assert(infos[1].address_constructed == addresses[1]);
+        assert(infos[2].address_constructed == addresses[2]);
+
+        delete[] x;
+        assert(infos[0].address_destroyed == addresses[0]);
+        assert(infos[1].address_destroyed == addresses[1]);
+        assert(infos[2].address_destroyed == addresses[2]);
+#endif
+    }
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.indirect.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.indirect.pass.cpp
new file mode 100644
index 0000000000000..ae4c3fc7655d4
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.indirect.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new[](std::size_t, std::nothrow_t const&);
+
+// Test that we can replace the operator by replacing `operator new[](std::size_t)` (the throwing version).
+
+// UNSUPPORTED: sanitizer-new-delete
+// XFAIL: libcpp-no-vcruntime
+// XFAIL: LIBCXX-AIX-FIXME
+
+// TODO: Investigate why this fails on Windows
+// XFAIL: target={{.+}}-windows-msvc
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+
+#include "test_macros.h"
+
+int new_called = 0;
+int delete_called = 0;
+
+TEST_WORKAROUND_BUG_109234844_WEAK
+void* operator new[](std::size_t s) TEST_THROW_SPEC(std::bad_alloc) {
+    ++new_called;
+    void* ret = std::malloc(s);
+    if (!ret) std::abort(); // placate MSVC's unchecked malloc warning
+    return ret;
+}
+
+void operator delete(void* p) TEST_NOEXCEPT {
+    ++delete_called;
+    std::free(p);
+}
+
+int main(int, char**) {
+    new_called = delete_called = 0;
+    int* x = new (std::nothrow) int[3];
+    assert(x != nullptr);
+    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1);
+
+    delete[] x;
+    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(delete_called == 1);
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.pass.cpp
new file mode 100644
index 0000000000000..b85e15ce64b48
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.replace.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new[](std::size_t, std::nothrow_t const&);
+
+// Test that we can replace the operator by defining our own.
+
+// UNSUPPORTED: sanitizer-new-delete
+// XFAIL: libcpp-no-vcruntime
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+
+#include "test_macros.h"
+
+int new_nothrow_called = 0;
+int delete_called = 0;
+
+void* operator new[](std::size_t s, std::nothrow_t const&) TEST_NOEXCEPT {
+    ++new_nothrow_called;
+    return std::malloc(s);
+}
+
+void operator delete[](void* p) TEST_NOEXCEPT {
+    ++delete_called;
+    std::free(p);
+}
+
+int main(int, char**) {
+    new_nothrow_called = delete_called = 0;
+    int* x = new (std::nothrow) int[3];
+    assert(x != nullptr);
+    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_nothrow_called == 1);
+
+    assert(delete_called == 0);
+    delete[] x;
+    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(delete_called == 1);
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp
deleted file mode 100644
index 868abe5c517d2..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t.pass.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14
-
-// asan and msan will not call the new handler.
-// UNSUPPORTED: sanitizer-new-delete
-
-// We get availability markup errors when aligned allocation is missing
-// XFAIL: availability-aligned_allocation-missing
-
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
-// nor does the dynamic library shipped with z/OS.
-// UNSUPPORTED: target={{.+}}-zos{{.*}}
-
-// test operator new
-
-#include <new>
-#include <cstddef>
-#include <cassert>
-#include <cstdint>
-#include <limits>
-
-#include "test_macros.h"
-
-constexpr auto OverAligned = __STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2;
-
-int new_handler_called = 0;
-
-void my_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(my_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(int, char**)
-{
-    {
-        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();
-    }
-
-  return 0;
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp
deleted file mode 100644
index 7aa31a9e8b058..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow.pass.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14
-
-// asan and msan will not call the new handler.
-// UNSUPPORTED: sanitizer-new-delete
-
-// We get availability markup errors when aligned allocation is missing
-// XFAIL: availability-aligned_allocation-missing
-
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
-// nor does the dynamic library shipped with z/OS.
-// UNSUPPORTED: target={{.+}}-zos{{.*}}
-
-// test operator new (nothrow)
-
-#include <new>
-#include <cstddef>
-#include <cstdint>
-#include <cassert>
-#include <limits>
-
-#include "test_macros.h"
-
-constexpr auto OverAligned = __STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2;
-
-int new_handler_called = 0;
-
-void my_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(my_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(int, char**)
-{
-    {
-        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();
-    }
-
-  return 0;
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp
deleted file mode 100644
index a0845ebc19d99..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_nothrow_replace.pass.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14
-// UNSUPPORTED: sanitizer-new-delete
-
-// XFAIL: LIBCXX-AIX-FIXME
-
-// We get availability markup errors when aligned allocation is missing
-// XFAIL: availability-aligned_allocation-missing
-
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
-// nor does the dynamic library shipped with z/OS.
-// UNSUPPORTED: target={{.+}}-zos{{.*}}
-
-// test operator new nothrow by replacing only operator new
-
-#include <new>
-#include <cstddef>
-#include <cstdlib>
-#include <cassert>
-#include <limits>
-
-#include "test_macros.h"
-
-constexpr auto OverAligned = __STDCPP_DEFAULT_NEW_ALIGNMENT__ * 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) TEST_THROW_SPEC(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) TEST_NOEXCEPT
-{
-    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(p == Buff);
-    assert(static_cast<std::size_t>(a) == OverAligned);
-    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called);
-    --new_called;
-}
-
-int main(int, char**)
-{
-    {
-        A* ap = new (std::nothrow) A[2];
-        assert(ap);
-        assert(A_constructed == 2);
-        ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called);
-        delete [] ap;
-        assert(A_constructed == 0);
-        ASSERT_WITH_OPERATOR_NEW_FALLBACKS(!new_called);
-    }
-    {
-        B* bp = new (std::nothrow) B[2];
-        assert(bp);
-        assert(B_constructed == 2);
-        ASSERT_WITH_OPERATOR_NEW_FALLBACKS(!new_called);
-        delete [] bp;
-        ASSERT_WITH_OPERATOR_NEW_FALLBACKS(!new_called);
-        assert(!B_constructed);
-    }
-
-  return 0;
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp
deleted file mode 100644
index 6ac345016ced6..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_align_val_t_replace.pass.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14
-// UNSUPPORTED: sanitizer-new-delete
-
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
-// nor does the dynamic library shipped with z/OS.
-// UNSUPPORTED: target={{.+}}-zos{{.*}}
-
-// test operator new replacement
-
-#include <new>
-#include <cstddef>
-#include <cstdlib>
-#include <cstdint>
-#include <cassert>
-#include <limits>
-
-#include "test_macros.h"
-
-constexpr auto OverAligned = __STDCPP_DEFAULT_NEW_ALIGNMENT__ * 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) TEST_THROW_SPEC(std::bad_alloc)
-{
-    assert(new_called == 0); // We already allocated
-    assert(s <= sizeof(DummyData));
-    assert(static_cast<std::size_t>(a) == OverAligned);
-    ++new_called;
-    void *Ret = DummyData;
-    DoNotOptimize(Ret);
-    return Ret;
-}
-
-void  operator delete[](void* p, std::align_val_t) TEST_NOEXCEPT
-{
-    assert(new_called == 1);
-    --new_called;
-    assert(p == DummyData);
-    DoNotOptimize(p);
-}
-
-
-int main(int, char**)
-{
-    {
-        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);
-    }
-
-  return 0;
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp
deleted file mode 100644
index 55dc5c7533403..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array.pass.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// test operator new[]
-// NOTE: asan and msan will not call the new handler.
-// UNSUPPORTED: sanitizer-new-delete
-
-
-#include <new>
-#include <cstddef>
-#include <cassert>
-#include <limits>
-
-#include "test_macros.h"
-
-int new_handler_called = 0;
-
-void my_new_handler()
-{
-    ++new_handler_called;
-    std::set_new_handler(0);
-}
-
-int A_constructed = 0;
-
-struct A
-{
-    A() {++A_constructed;}
-    ~A() {--A_constructed;}
-};
-
-int main(int, char**)
-{
-#ifndef TEST_HAS_NO_EXCEPTIONS
-    std::set_new_handler(my_new_handler);
-    try
-    {
-        void* vp = operator new[] (std::numeric_limits<std::size_t>::max());
-        DoNotOptimize(vp);
-        assert(false);
-    }
-    catch (std::bad_alloc&)
-    {
-        assert(new_handler_called == 1);
-    }
-    catch (...)
-    {
-        assert(false);
-    }
-#endif
-    A* ap = new A[3];
-    DoNotOptimize(ap);
-    assert(ap);
-    assert(A_constructed == 3);
-    delete [] ap;
-    DoNotOptimize(ap);
-    assert(A_constructed == 0);
-
-  return 0;
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp
deleted file mode 100644
index ce8b18d043641..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_array_nothrow.pass.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// test operator new [] (nothrow)
-// NOTE: asan and msan will not call the new handler.
-// UNSUPPORTED: sanitizer-new-delete
-
-
-#include <new>
-#include <cstddef>
-#include <cassert>
-#include <limits>
-
-#include "test_macros.h"
-
-int new_handler_called = 0;
-
-void my_new_handler()
-{
-    ++new_handler_called;
-    std::set_new_handler(0);
-}
-
-int A_constructed = 0;
-
-struct A
-{
-    A() {++A_constructed;}
-    ~A() {--A_constructed;}
-};
-
-int main(int, char**)
-{
-    new_handler_called = 0;
-    std::set_new_handler(my_new_handler);
-#ifndef TEST_HAS_NO_EXCEPTIONS
-    try
-#endif
-    {
-        void* vp = operator new [] (std::numeric_limits<std::size_t>::max(), std::nothrow);
-        DoNotOptimize(vp);
-        assert(new_handler_called == 1);
-        assert(vp == 0);
-    }
-#ifndef TEST_HAS_NO_EXCEPTIONS
-    catch (...)
-    {
-        assert(false);
-    }
-#endif
-    A* ap = new(std::nothrow) A[3];
-    DoNotOptimize(ap);
-    assert(ap);
-    assert(A_constructed == 3);
-    delete [] ap;
-    DoNotOptimize(ap);
-    assert(A_constructed == 0);
-
-  return 0;
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size.verify.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size.verify.cpp
deleted file mode 100644
index 8e979165219dd..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size.verify.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <new>
-
-// void* operator new[](std::size_t);
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// REQUIRES: -faligned-allocation
-// ADDITIONAL_COMPILE_FLAGS: -faligned-allocation
-
-#include <new>
-
-void f() {
-    ::operator new[](4);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align.verify.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align.verify.cpp
deleted file mode 100644
index 530e152c5e41a..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align.verify.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <new>
-
-// void* operator new[](std::size_t, std::align_val_t);
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
-// nor does the dynamic library shipped with z/OS.
-// UNSUPPORTED: target={{.+}}-zos{{.*}}
-
-// REQUIRES: -faligned-allocation
-// ADDITIONAL_COMPILE_FLAGS: -faligned-allocation
-
-#include <new>
-
-void f() {
-    ::operator new[](4, std::align_val_t{4});  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align_nothrow.verify.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align_nothrow.verify.cpp
deleted file mode 100644
index 33100736299c2..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_align_nothrow.verify.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <new>
-
-// void* operator new[](std::size_t, std::align_val_t, std::nothrow_t &);
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
-// nor does the dynamic library shipped with z/OS.
-// UNSUPPORTED: target={{.+}}-zos{{.*}}
-
-// REQUIRES: -faligned-allocation
-// ADDITIONAL_COMPILE_FLAGS: -faligned-allocation
-
-#include <new>
-
-void f() {
-    ::operator new[](4, std::align_val_t{4}, std::nothrow);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_nothrow.verify.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_nothrow.verify.cpp
deleted file mode 100644
index fd954d4e70fca..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/new_size_nothrow.verify.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <new>
-
-// void* operator new[](std::size_t, std::nothrow_t &);
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// REQUIRES: -faligned-allocation
-// ADDITIONAL_COMPILE_FLAGS: -faligned-allocation
-
-#include <new>
-
-void f() {
-    ::operator new[](4, std::nothrow);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/nodiscard.verify.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..cb5ea43fdef36
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/nodiscard.verify.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// [[nodiscard]] void* operator new[](std::size_t);
+// [[nodiscard]] void* operator new[](std::size_t, std::nothrow_t const&);
+// [[nodiscard]] void* operator new[](std::size_t, std::align_val_t);
+// [[nodiscard]] void* operator new[](std::size_t, std::align_val_t, std::nothrow_t const&);
+
+// [[nodiscard]] is not supported at all in c++03
+// UNSUPPORTED: c++03
+
+// [[nodiscard]] enabled before C++20 in libc++ as an extension
+// UNSUPPORTED: (c++11 || c++14 || c++17) && !stdlib=libc++
+
+// We get availability markup errors when aligned allocation is missing
+// XFAIL: availability-aligned_allocation-missing
+
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
+// nor does the dynamic library shipped with z/OS.
+// UNSUPPORTED: target={{.+}}-zos{{.*}}
+
+#include <new>
+
+#include "test_macros.h"
+
+void f() {
+    ::operator new[](4);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    ::operator new[](4, std::nothrow);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+#if TEST_STD_VER >= 17
+    ::operator new[](4, std::align_val_t{4});  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    ::operator new[](4, std::align_val_t{4}, std::nothrow);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp
index 4814be37a6ff3..c2021c5d84e9c 100644
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/delete_align_val_t_replace.pass.cpp
@@ -10,10 +10,7 @@
 
 // UNSUPPORTED: sanitizer-new-delete, c++03, c++11, c++14
 
-// Aligned allocation was not provided before macosx10.14 and as a result we
-// get availability errors when the deployment target is older than macosx10.14.
-
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
 // nor does the dynamic library shipped with z/OS.
 // UNSUPPORTED: target={{.+}}-zos{{.*}}
 

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.pass.cpp
deleted file mode 100644
index 448da1717900e..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.pass.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// test operator new
-
-// asan and msan will not call the new handler.
-// UNSUPPORTED: sanitizer-new-delete
-
-#include <new>
-#include <cstddef>
-#include <cassert>
-#include <limits>
-
-#include "test_macros.h"
-
-int new_handler_called = 0;
-
-void my_new_handler()
-{
-    ++new_handler_called;
-    std::set_new_handler(0);
-}
-
-bool A_constructed = false;
-
-struct A
-{
-    A() {A_constructed = true;}
-    ~A() {A_constructed = false;}
-};
-
-int main(int, char**)
-{
-#ifndef TEST_HAS_NO_EXCEPTIONS
-    std::set_new_handler(my_new_handler);
-    try
-    {
-        void* vp = operator new (std::numeric_limits<std::size_t>::max());
-        ((void)vp);
-        assert(false);
-    }
-    catch (std::bad_alloc&)
-    {
-        assert(new_handler_called == 1);
-    }
-    catch (...)
-    {
-        assert(false);
-    }
-#endif
-    A* ap = new A;
-    assert(ap);
-    assert(A_constructed);
-    delete ap;
-    assert(!A_constructed);
-
-  return 0;
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size.pass.cpp
new file mode 100644
index 0000000000000..729ef3ec46b0c
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size.pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new(std::size_t);
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+#include "../types.h"
+
+int new_handler_called = 0;
+
+void my_new_handler() {
+    ++new_handler_called;
+    std::set_new_handler(nullptr);
+}
+
+int main(int, char**) {
+    // Test that we can call the function directly
+    {
+        void* x = operator new(10);
+        assert(x != nullptr);
+        operator delete(x);
+    }
+
+    // Test that the new handler is called if allocation fails
+    {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+        std::set_new_handler(my_new_handler);
+        try {
+            void* x = operator new(std::numeric_limits<std::size_t>::max());
+            (void)x;
+            assert(false);
+        } catch (std::bad_alloc const&) {
+            assert(new_handler_called == 1);
+        } catch (...) {
+            assert(false);
+        }
+#endif
+    }
+
+    // Test that a new expression constructs the right object
+    // and a delete expression deletes it
+    {
+        LifetimeInformation info;
+        TrackLifetime* x = new TrackLifetime(info);
+        assert(x != nullptr);
+        assert(info.address_constructed == x);
+
+        delete x;
+        assert(info.address_destroyed == x);
+    }
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size.replace.pass.cpp
similarity index 61%
rename from libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp
rename to libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size.replace.pass.cpp
index 807d1fd67f5df..a03313e5872ef 100644
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_replace.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size.replace.pass.cpp
@@ -6,7 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test operator new replacement
+// void* operator new(std::size_t);
+
+// Test that we can replace the operator by defining our own.
 
 // UNSUPPORTED: sanitizer-new-delete
 
@@ -14,46 +16,32 @@
 #include <cstddef>
 #include <cstdlib>
 #include <cassert>
-#include <limits>
 
 #include "test_macros.h"
 
 int new_called = 0;
+int delete_called = 0;
 
-void* operator new(std::size_t s) TEST_THROW_SPEC(std::bad_alloc)
-{
+void* operator new(std::size_t s) TEST_THROW_SPEC(std::bad_alloc) {
     ++new_called;
     void* ret = std::malloc(s);
     if (!ret) std::abort(); // placate MSVC's unchecked malloc warning
     return ret;
 }
 
-void  operator delete(void* p) TEST_NOEXCEPT
-{
-    --new_called;
+void operator delete(void* p) TEST_NOEXCEPT {
+    ++delete_called;
     std::free(p);
 }
 
-bool A_constructed = false;
-
-struct A
-{
-    A() {A_constructed = true;}
-    ~A() {A_constructed = false;}
-};
-
-int main(int, char**)
-{
-    new_called = 0;
-    A *ap = new A;
-    DoNotOptimize(ap);
-    assert(ap);
-    assert(A_constructed);
-    assert(new_called);
-    delete ap;
-    DoNotOptimize(ap);
-    assert(!A_constructed);
-    assert(!new_called);
-
-  return 0;
+int main(int, char**) {
+    new_called = delete_called = 0;
+    int* x = new int(3);
+    assert(x != nullptr);
+    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1);
+
+    delete x;
+    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(delete_called == 1);
+
+    return 0;
 }

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align.pass.cpp
new file mode 100644
index 0000000000000..49b797f69d09b
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new(std::size_t, std::align_val_t);
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// We get availability markup errors when aligned allocation is missing
+// XFAIL: availability-aligned_allocation-missing
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: sanitizer-new-delete
+
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
+// nor does the dynamic library shipped with z/OS.
+// UNSUPPORTED: target={{.+}}-zos{{.*}}
+
+#include <new>
+#include <cstddef>
+#include <cassert>
+#include <cstdint>
+#include <limits>
+
+#include "test_macros.h"
+#include "../types.h"
+
+int new_handler_called = 0;
+
+void my_new_handler() {
+    ++new_handler_called;
+    std::set_new_handler(nullptr);
+}
+
+int main(int, char**) {
+    // Test that we can call the function directly
+    {
+        void* x = operator new(10, static_cast<std::align_val_t>(64));
+        assert(x != nullptr);
+        assert(reinterpret_cast<std::uintptr_t>(x) % 64 == 0);
+        operator delete(x, static_cast<std::align_val_t>(64));
+    }
+
+    // Test that the new handler is called if allocation fails
+    {
+#ifndef TEST_HAS_NO_EXCEPTIONS
+        std::set_new_handler(my_new_handler);
+        try {
+            void* x = operator new(std::numeric_limits<std::size_t>::max(),
+                                   static_cast<std::align_val_t>(32));
+            (void)x;
+            assert(false);
+        } catch (std::bad_alloc const&) {
+            assert(new_handler_called == 1);
+        } catch (...) {
+            assert(false);
+        }
+#endif
+    }
+
+    // Test that a new expression constructs the right object
+    // and a delete expression deletes it
+    {
+        LifetimeInformation info;
+        TrackLifetimeOverAligned* x = new TrackLifetimeOverAligned(info);
+        assert(x != nullptr);
+        assert(reinterpret_cast<std::uintptr_t>(x) % alignof(TrackLifetimeOverAligned) == 0);
+        assert(info.address_constructed == x);
+
+        delete x;
+        assert(info.address_destroyed == x);
+    }
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align.replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align.replace.pass.cpp
new file mode 100644
index 0000000000000..87d061a9d1a3c
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align.replace.pass.cpp
@@ -0,0 +1,82 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new(std::size_t, std::align_val_t);
+
+// Test that we can replace the operator by defining our own.
+
+// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: sanitizer-new-delete
+
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
+// nor does the dynamic library shipped with z/OS.
+// UNSUPPORTED: target={{.+}}-zos{{.*}}
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cstdint>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+#include "../types.h"
+
+int new_called = 0;
+int delete_called = 0;
+
+alignas(OverAligned) char DummyData[alignof(OverAligned)];
+
+void* operator new(std::size_t s, std::align_val_t a) {
+    assert(s <= sizeof(DummyData));
+    assert(static_cast<std::size_t>(a) == alignof(OverAligned));
+    ++new_called;
+    return DummyData;
+}
+
+void operator delete(void*, std::align_val_t) noexcept {
+    ++delete_called;
+    // nothing to delete, we didn't actually allocate in `operator new`
+}
+
+int main(int, char**) {
+    // Test with an overaligned type
+    {
+        new_called = delete_called = 0;
+        OverAligned* x = new OverAligned;
+        assert(static_cast<void*>(x) == DummyData);
+        assert(new_called == 1);
+
+        delete x;
+        assert(delete_called == 1);
+    }
+
+    // Test with a type that is right on the verge of being overaligned
+    {
+        new_called = delete_called = 0;
+        MaxAligned* x = new MaxAligned;
+        assert(x != nullptr);
+        assert(new_called == 0);
+
+        delete x;
+        assert(delete_called == 0);
+    }
+
+    // Test with a type that is clearly not overaligned
+    {
+        new_called = delete_called = 0;
+        int* x = new int;
+        assert(x != nullptr);
+        assert(new_called == 0);
+
+        delete x;
+        assert(delete_called == 0);
+    }
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.pass.cpp
new file mode 100644
index 0000000000000..7149a377f983a
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.pass.cpp
@@ -0,0 +1,71 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new(std::size_t, std::align_val_t, std::nothrow_t const&);
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// We get availability markup errors when aligned allocation is missing
+// XFAIL: availability-aligned_allocation-missing
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: sanitizer-new-delete
+
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
+// nor does the dynamic library shipped with z/OS.
+// UNSUPPORTED: target={{.+}}-zos{{.*}}
+
+#include <new>
+#include <cstddef>
+#include <cstdint>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+#include "../types.h"
+
+int new_handler_called = 0;
+
+void my_new_handler() {
+    ++new_handler_called;
+    std::set_new_handler(nullptr);
+}
+
+int main(int, char**) {
+    // Test that we can call the function directly
+    {
+        void* x = operator new(10, static_cast<std::align_val_t>(64), std::nothrow);
+        assert(x != nullptr);
+        assert(reinterpret_cast<std::uintptr_t>(x) % 64 == 0);
+        operator delete(x, static_cast<std::align_val_t>(64), std::nothrow);
+    }
+
+    // Test that the new handler is called and we return nullptr if allocation fails
+    {
+        std::set_new_handler(my_new_handler);
+        void* x = operator new(std::numeric_limits<std::size_t>::max(),
+                               static_cast<std::align_val_t>(32), std::nothrow);
+        assert(new_handler_called == 1);
+        assert(x == nullptr);
+    }
+
+    // Test that a new expression constructs the right object
+    // and a delete expression deletes it
+    {
+        LifetimeInformation info;
+        TrackLifetimeOverAligned* x = new (std::nothrow) TrackLifetimeOverAligned(info);
+        assert(x != nullptr);
+        assert(reinterpret_cast<std::uintptr_t>(x) % alignof(TrackLifetimeOverAligned) == 0);
+        assert(info.address_constructed == x);
+
+        delete x;
+        assert(info.address_destroyed == x);
+    }
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.indirect.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.indirect.pass.cpp
new file mode 100644
index 0000000000000..31fa92766c744
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.indirect.pass.cpp
@@ -0,0 +1,90 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new(std::size_t, std::align_val_t, std::nothrow_t const&);
+
+// Test that we can replace the operator by replacing `operator new(std::size_t, std::align_val_t)` (the throwing version).
+
+// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: sanitizer-new-delete
+
+// XFAIL: LIBCXX-AIX-FIXME
+
+// We get availability markup errors when aligned allocation is missing
+// XFAIL: availability-aligned_allocation-missing
+
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
+// nor does the dynamic library shipped with z/OS.
+// UNSUPPORTED: target={{.+}}-zos{{.*}}
+
+// TODO: Investigate why this fails on MinGW-shared
+// UNSUPPORTED: target={{.+}}-windows-gnu
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+#include "../types.h"
+
+int new_called = 0;
+int delete_called = 0;
+
+alignas(OverAligned) char DummyData[alignof(OverAligned)];
+
+TEST_WORKAROUND_BUG_109234844_WEAK
+void* operator new(std::size_t s, std::align_val_t a) {
+    assert(s <= sizeof(DummyData));
+    assert(static_cast<std::size_t>(a) == alignof(OverAligned));
+    ++new_called;
+    return DummyData;
+}
+
+void operator delete(void*, std::align_val_t) noexcept {
+    ++delete_called;
+    // nothing to delete, we didn't actually allocate in `operator new`
+}
+
+int main(int, char**) {
+    // Test with an overaligned type
+    {
+        new_called = delete_called = 0;
+        OverAligned* x = new (std::nothrow) OverAligned;
+        assert(static_cast<void*>(x) == DummyData);
+        ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1);
+
+        delete x;
+        ASSERT_WITH_OPERATOR_NEW_FALLBACKS(delete_called == 1);
+    }
+
+    // Test with a type that is right on the verge of being overaligned
+    {
+        new_called = delete_called = 0;
+        MaxAligned* x = new (std::nothrow) MaxAligned;
+        assert(x != nullptr);
+        assert(new_called == 0);
+
+        delete x;
+        assert(delete_called == 0);
+    }
+
+    // Test with a type that is clearly not overaligned
+    {
+        new_called = delete_called = 0;
+        int* x = new (std::nothrow) int;
+        assert(x != nullptr);
+        assert(new_called == 0);
+
+        delete x;
+        assert(delete_called == 0);
+    }
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.pass.cpp
new file mode 100644
index 0000000000000..25a3bf767307f
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.replace.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new(std::size_t, std::align_val_t, std::nothrow_t const&);
+
+// Test that we can replace the operator by defining our own.
+
+// UNSUPPORTED: c++03, c++11, c++14
+// UNSUPPORTED: sanitizer-new-delete
+
+// We get availability markup errors when aligned allocation is missing
+// XFAIL: availability-aligned_allocation-missing
+
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
+// nor does the dynamic library shipped with z/OS.
+// UNSUPPORTED: target={{.+}}-zos{{.*}}
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+#include "../types.h"
+
+int new_nothrow_called = 0;
+int delete_called = 0;
+
+alignas(OverAligned) char DummyData[alignof(OverAligned)];
+
+void* operator new(std::size_t s, std::align_val_t a, std::nothrow_t const&) noexcept {
+    assert(s <= sizeof(DummyData));
+    assert(static_cast<std::size_t>(a) == alignof(OverAligned));
+    ++new_nothrow_called;
+    return DummyData;
+}
+
+void operator delete(void*, std::align_val_t) noexcept {
+    ++delete_called;
+    // nothing to delete, we didn't actually allocate in `operator new`
+}
+
+int main(int, char**) {
+    // Test with an overaligned type
+    {
+        new_nothrow_called = delete_called = 0;
+        OverAligned* x = new (std::nothrow) OverAligned;
+        assert(static_cast<void*>(x) == DummyData);
+        ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_nothrow_called == 1);
+
+        delete x;
+        ASSERT_WITH_OPERATOR_NEW_FALLBACKS(delete_called == 1);
+    }
+
+    // Test with a type that is right on the verge of being overaligned
+    {
+        new_nothrow_called = delete_called = 0;
+        MaxAligned* x = new (std::nothrow) MaxAligned;
+        assert(x != nullptr);
+        assert(new_nothrow_called == 0);
+
+        delete x;
+        assert(delete_called == 0);
+    }
+
+    // Test with a type that is clearly not overaligned
+    {
+        new_nothrow_called = delete_called = 0;
+        int* x = new (std::nothrow) int;
+        assert(x != nullptr);
+        assert(new_nothrow_called == 0);
+
+        delete x;
+        assert(delete_called == 0);
+    }
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.pass.cpp
new file mode 100644
index 0000000000000..398de0068aba1
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.pass.cpp
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new(std::size_t, std::nothrow_t const&);
+
+// asan and msan will not call the new handler.
+// UNSUPPORTED: sanitizer-new-delete
+
+#include <new>
+#include <cstddef>
+#include <cassert>
+#include <limits>
+
+#include "test_macros.h"
+#include "../types.h"
+
+int new_handler_called = 0;
+
+void my_new_handler() {
+    ++new_handler_called;
+    std::set_new_handler(nullptr);
+}
+
+int main(int, char**) {
+    // Test that we can call the function directly
+    {
+        void* x = operator new(10, std::nothrow);
+        assert(x != nullptr);
+        operator delete(x, std::nothrow);
+    }
+
+    // Test that the new handler is called and we return nullptr if allocation fails
+    {
+        std::set_new_handler(my_new_handler);
+        void* x = operator new(std::numeric_limits<std::size_t>::max(), std::nothrow);
+        assert(new_handler_called == 1);
+        assert(x == nullptr);
+    }
+
+    // Test that a new expression constructs the right object
+    // and a delete expression deletes it
+    {
+        LifetimeInformation info;
+        TrackLifetime* x = new (std::nothrow) TrackLifetime(info);
+        assert(x != nullptr);
+        assert(info.address_constructed == x);
+
+        delete x;
+        assert(info.address_destroyed == x);
+    }
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.replace.indirect.pass.cpp
similarity index 58%
rename from libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp
rename to libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.replace.indirect.pass.cpp
index d21f8f86ac900..2ae0dfa4f1abc 100644
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow_replace.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.replace.indirect.pass.cpp
@@ -6,7 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test operator new nothrow by replacing only operator new
+// void* operator new(std::size_t, std::nothrow_t const&);
+
+// Test that we can replace the operator by replacing `operator new(std::size_t)` (the throwing version).
 
 // UNSUPPORTED: sanitizer-new-delete
 // XFAIL: libcpp-no-vcruntime
@@ -16,46 +18,33 @@
 #include <cstddef>
 #include <cstdlib>
 #include <cassert>
-#include <limits>
 
 #include "test_macros.h"
 
 int new_called = 0;
+int delete_called = 0;
 
-void* operator new(std::size_t s) TEST_THROW_SPEC(std::bad_alloc)
-{
+TEST_WORKAROUND_BUG_109234844_WEAK
+void* operator new(std::size_t s) TEST_THROW_SPEC(std::bad_alloc) {
     ++new_called;
     void* ret = std::malloc(s);
     if (!ret) std::abort(); // placate MSVC's unchecked malloc warning
     return ret;
 }
 
-void  operator delete(void* p) TEST_NOEXCEPT
-{
-    --new_called;
+void operator delete(void* p) TEST_NOEXCEPT {
+    ++delete_called;
     std::free(p);
 }
 
-bool A_constructed = false;
-
-struct A
-{
-    A() {A_constructed = true;}
-    ~A() {A_constructed = false;}
-};
-
-int main(int, char**)
-{
-    new_called = 0;
-    A *ap = new (std::nothrow) A;
-    DoNotOptimize(ap);
-    assert(ap);
-    assert(A_constructed);
-    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called);
-    delete ap;
-    DoNotOptimize(ap);
-    assert(!A_constructed);
-    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(!new_called);
-
-  return 0;
+int main(int, char**) {
+    new_called = delete_called = 0;
+    int* x = new (std::nothrow) int(3);
+    assert(x != nullptr);
+    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called == 1);
+
+    delete x;
+    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(delete_called == 1);
+
+    return 0;
 }

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.replace.pass.cpp
new file mode 100644
index 0000000000000..784d648409e86
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.replace.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// void* operator new(std::size_t, std::nothrow_t const&);
+
+// Test that we can replace the operator by defining our own.
+
+// UNSUPPORTED: sanitizer-new-delete
+// XFAIL: libcpp-no-vcruntime
+
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <cassert>
+
+#include "test_macros.h"
+
+int new_nothrow_called = 0;
+int delete_called = 0;
+
+void* operator new(std::size_t s, std::nothrow_t const&) TEST_NOEXCEPT {
+    ++new_nothrow_called;
+    return std::malloc(s);
+}
+
+void operator delete(void* p) TEST_NOEXCEPT {
+    ++delete_called;
+    std::free(p);
+}
+
+int main(int, char**) {
+    new_nothrow_called = delete_called = 0;
+    int* x = new (std::nothrow) int(3);
+    assert(x != nullptr);
+    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_nothrow_called == 1);
+
+    assert(delete_called == 0);
+    delete x;
+    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(delete_called == 1);
+
+    return 0;
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp
deleted file mode 100644
index bd3c73790dd90..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t.pass.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14
-
-// We get availability markup errors when aligned allocation is missing
-// XFAIL: availability-aligned_allocation-missing
-
-// asan and msan will not call the new handler.
-// UNSUPPORTED: sanitizer-new-delete
-
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
-// nor does the dynamic library shipped with z/OS.
-// UNSUPPORTED: target={{.+}}-zos{{.*}}
-
-// test operator new
-
-#include <new>
-#include <cstddef>
-#include <cassert>
-#include <cstdint>
-#include <limits>
-
-#include "test_macros.h"
-
-constexpr auto OverAligned = __STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2;
-
-int new_handler_called = 0;
-
-void my_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(my_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(int, char**)
-{
-    {
-        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();
-    }
-
-  return 0;
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp
deleted file mode 100644
index de481672a0801..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow.pass.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14
-
-// We get availability markup errors when aligned allocation is missing
-// XFAIL: availability-aligned_allocation-missing
-
-// asan and msan will not call the new handler.
-// UNSUPPORTED: sanitizer-new-delete
-
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
-// nor does the dynamic library shipped with z/OS.
-// UNSUPPORTED: target={{.+}}-zos{{.*}}
-
-// test operator new (nothrow)
-
-#include <new>
-#include <cstddef>
-#include <cstdint>
-#include <cassert>
-#include <limits>
-
-#include "test_macros.h"
-
-constexpr auto OverAligned = __STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2;
-
-int new_handler_called = 0;
-
-void my_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(my_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(int, char**)
-{
-    {
-        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();
-    }
-
-  return 0;
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp
deleted file mode 100644
index 285c88fcdb860..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_nothrow_replace.pass.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14
-// UNSUPPORTED: sanitizer-new-delete
-
-// XFAIL: LIBCXX-AIX-FIXME
-
-// We get availability markup errors when aligned allocation is missing
-// XFAIL: availability-aligned_allocation-missing
-
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
-// nor does the dynamic library shipped with z/OS.
-// UNSUPPORTED: target={{.+}}-zos{{.*}}
-
-// test operator new nothrow by replacing only operator new
-
-#include <new>
-#include <cstddef>
-#include <cstdlib>
-#include <cassert>
-#include <limits>
-
-#include "test_macros.h"
-
-constexpr auto OverAligned = __STDCPP_DEFAULT_NEW_ALIGNMENT__ * 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) TEST_THROW_SPEC(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) TEST_NOEXCEPT
-{
-    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(p == Buff);
-    assert(static_cast<std::size_t>(a) == OverAligned);
-    ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called);
-    --new_called;
-}
-
-
-int main(int, char**)
-{
-    {
-        A* ap = new (std::nothrow) A;
-        assert(ap);
-        assert(A_constructed);
-        ASSERT_WITH_OPERATOR_NEW_FALLBACKS(new_called);
-        delete ap;
-        assert(!A_constructed);
-        ASSERT_WITH_OPERATOR_NEW_FALLBACKS(!new_called);
-    }
-    {
-        B* bp = new (std::nothrow) B;
-        assert(bp);
-        assert(B_constructed);
-        ASSERT_WITH_OPERATOR_NEW_FALLBACKS(!new_called);
-        delete bp;
-        ASSERT_WITH_OPERATOR_NEW_FALLBACKS(!new_called);
-        assert(!B_constructed);
-    }
-
-  return 0;
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp
deleted file mode 100644
index 330c26a0364fe..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_align_val_t_replace.pass.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14
-// UNSUPPORTED: sanitizer-new-delete
-
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
-// nor does the dynamic library shipped with z/OS.
-// UNSUPPORTED: target={{.+}}-zos{{.*}}
-
-// test operator new replacement
-
-#include <new>
-#include <cstddef>
-#include <cstdlib>
-#include <cstdint>
-#include <cassert>
-#include <limits>
-
-#include "test_macros.h"
-
-constexpr auto OverAligned = __STDCPP_DEFAULT_NEW_ALIGNMENT__ * 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) TEST_THROW_SPEC(std::bad_alloc)
-{
-    assert(new_called == 0); // We already allocated
-    assert(s <= sizeof(DummyData));
-    assert(static_cast<std::size_t>(a) == OverAligned);
-    ++new_called;
-    void *Ret = DummyData;
-    DoNotOptimize(Ret);
-    return Ret;
-}
-
-void  operator delete(void* p, std::align_val_t) TEST_NOEXCEPT
-{
-    assert(new_called == 1);
-    --new_called;
-    assert(p == DummyData);
-    DoNotOptimize(DummyData);
-}
-
-
-int main(int, char**)
-{
-    {
-        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);
-    }
-
-  return 0;
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp
deleted file mode 100644
index dfdf7d77e8016..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_nothrow.pass.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// test operator new (nothrow)
-
-// asan and msan will not call the new handler.
-// UNSUPPORTED: sanitizer-new-delete
-
-#include <new>
-#include <cstddef>
-#include <cassert>
-#include <limits>
-
-#include "test_macros.h"
-
-int new_handler_called = 0;
-
-void my_new_handler()
-{
-    ++new_handler_called;
-    std::set_new_handler(0);
-}
-
-bool A_constructed = false;
-
-struct A
-{
-    A() {A_constructed = true;}
-    ~A() {A_constructed = false;}
-};
-
-int main(int, char**)
-{
-    std::set_new_handler(my_new_handler);
-#ifndef TEST_HAS_NO_EXCEPTIONS
-    try
-#endif
-    {
-        void* vp = operator new (std::numeric_limits<std::size_t>::max(), std::nothrow);
-        assert(new_handler_called == 1);
-        assert(vp == 0);
-    }
-#ifndef TEST_HAS_NO_EXCEPTIONS
-    catch (...)
-    {
-        assert(false);
-    }
-#endif
-    A* ap = new(std::nothrow) A;
-    assert(ap);
-    assert(A_constructed);
-    delete ap;
-    assert(!A_constructed);
-
-  return 0;
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size.verify.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size.verify.cpp
deleted file mode 100644
index d3ed46e7052b3..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size.verify.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <new>
-
-// void* operator new(std::size_t);
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-#include <new>
-
-void f() {
-    ::operator new(4); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align.verify.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align.verify.cpp
deleted file mode 100644
index 42a88615734a2..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align.verify.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <new>
-
-// void* operator new(std::size_t, std::align_val_t);
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
-// nor does the dynamic library shipped with z/OS.
-// UNSUPPORTED: target={{.+}}-zos{{.*}}
-
-// REQUIRES: -faligned-allocation
-// ADDITIONAL_COMPILE_FLAGS: -faligned-allocation
-
-#include <new>
-
-void f() {
-    ::operator new(4, std::align_val_t{4});  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align_nothrow.verify.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align_nothrow.verify.cpp
deleted file mode 100644
index 8dcdbe3ca28ee..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_align_nothrow.verify.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <new>
-
-// void* operator new(std::size_t, std::align_val_t, std::nothrow_t &);
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-// Libcxx when built for z/OS doesn't contain the aligned allocation functions,
-// nor does the dynamic library shipped with z/OS.
-// UNSUPPORTED: target={{.+}}-zos{{.*}}
-
-// REQUIRES: -faligned-allocation
-// ADDITIONAL_COMPILE_FLAGS: -faligned-allocation
-
-#include <new>
-
-void f() {
-    ::operator new(4, std::align_val_t{4}, std::nothrow);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_nothrow.verify.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_nothrow.verify.cpp
deleted file mode 100644
index 081769b7c4840..0000000000000
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/new_size_nothrow.verify.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <new>
-
-// void* operator new(std::size_t, std::nothrow_t &);
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-
-#include <new>
-
-void f() {
-    ::operator new(4, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
-}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/nodiscard.verify.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/nodiscard.verify.cpp
new file mode 100644
index 0000000000000..d7547ae5783d8
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/nodiscard.verify.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// [[nodiscard]] void* operator new(std::size_t);
+// [[nodiscard]] void* operator new(std::size_t, std::nothrow_t const&);
+// [[nodiscard]] void* operator new(std::size_t, std::align_val_t);
+// [[nodiscard]] void* operator new(std::size_t, std::align_val_t, std::nothrow_t const&);
+
+// [[nodiscard]] is not supported at all in c++03
+// UNSUPPORTED: c++03
+
+// [[nodiscard]] enabled before C++20 in libc++ as an extension
+// UNSUPPORTED: (c++11 || c++14 || c++17) && !stdlib=libc++
+
+// We get availability markup errors when aligned allocation is missing
+// XFAIL: availability-aligned_allocation-missing
+
+// Libc++ when built for z/OS doesn't contain the aligned allocation functions,
+// nor does the dynamic library shipped with z/OS.
+// UNSUPPORTED: target={{.+}}-zos{{.*}}
+
+#include <new>
+
+#include "test_macros.h"
+
+void f() {
+    ::operator new(4); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    ::operator new(4, std::nothrow); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+#if TEST_STD_VER >= 17
+    ::operator new(4, std::align_val_t{4});  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    ::operator new(4, std::align_val_t{4}, std::nothrow);  // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+#endif
+}

diff  --git a/libcxx/test/std/language.support/support.dynamic/new.delete/types.h b/libcxx/test/std/language.support/support.dynamic/new.delete/types.h
new file mode 100644
index 0000000000000..b32d94dcd9dcc
--- /dev/null
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/types.h
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_STD_LANGUAGE_SUPPORT_SUPPORT_DYNAMIC_NEW_DELETE_TYPES_H
+#define TEST_STD_LANGUAGE_SUPPORT_SUPPORT_DYNAMIC_NEW_DELETE_TYPES_H
+
+#include <cstddef>
+
+#include "test_macros.h"
+
+struct LifetimeInformation {
+    void* address_constructed = nullptr;
+    void* address_destroyed = nullptr;
+};
+
+struct TrackLifetime {
+    TrackLifetime(LifetimeInformation& info) : info_(&info) {
+        info_->address_constructed = this;
+    }
+    ~TrackLifetime() {
+        info_->address_destroyed = this;
+    }
+    LifetimeInformation* info_;
+};
+
+#if TEST_STD_VER >= 17
+struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) TrackLifetimeOverAligned {
+    TrackLifetimeOverAligned(LifetimeInformation& info) : info_(&info) {
+        info_->address_constructed = this;
+    }
+    ~TrackLifetimeOverAligned() {
+        info_->address_destroyed = this;
+    }
+    LifetimeInformation* info_;
+};
+
+struct alignas(std::max_align_t) TrackLifetimeMaxAligned {
+    TrackLifetimeMaxAligned(LifetimeInformation& info) : info_(&info) {
+        info_->address_constructed = this;
+    }
+    ~TrackLifetimeMaxAligned() {
+        info_->address_destroyed = this;
+    }
+    LifetimeInformation* info_;
+};
+
+struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) OverAligned {
+
+};
+
+struct alignas(std::max_align_t) MaxAligned {
+
+};
+#endif // TEST_STD_VER >= 17
+
+#endif // TEST_STD_LANGUAGE_SUPPORT_SUPPORT_DYNAMIC_NEW_DELETE_TYPES_H

diff  --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h
index c3f3d8675aa7a..624caf322aa37 100644
--- a/libcxx/test/support/test_macros.h
+++ b/libcxx/test/support/test_macros.h
@@ -440,4 +440,13 @@ inline void DoNotOptimize(Tp const& value) {
 #  define TEST_SHORT_WCHAR
 #endif
 
+// This is a temporary workaround for user-defined `operator new` definitions
+// not being picked up on Apple platforms in some circumstances. This is under
+// investigation and should be short-lived.
+#ifdef __APPLE__
+#  define TEST_WORKAROUND_BUG_109234844_WEAK __attribute__((weak))
+#else
+#  define TEST_WORKAROUND_BUG_109234844_WEAK /* nothing */
+#endif
+
 #endif // SUPPORT_TEST_MACROS_HPP


        


More information about the libcxx-commits mailing list