[libcxx-commits] [libcxx] [libc++] Remove macros for keeping std::allocator members and void specialization after C++20 (PR #85806)

Ilya Biryukov via libcxx-commits libcxx-commits at lists.llvm.org
Wed Mar 20 11:26:03 PDT 2024


https://github.com/ilya-biryukov updated https://github.com/llvm/llvm-project/pull/85806

>From 473aeaebb3a60c4d91c698f6b6cf24d46789fa87 Mon Sep 17 00:00:00 2001
From: Ilya Biryukov <ibiryukov at google.com>
Date: Tue, 19 Mar 2024 15:57:14 +0100
Subject: [PATCH 1/3] [libc++] Remove macros for keeping std::allocator members
 and void specialization after C++20

Fixes #75975.

Remove `_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS` for the LLVM 19
release, it was previously marked as deprecated in LLVM 18.

I believe that `_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION`
was only used by Google in conjunction with
`_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS`.

Removing both macros together should not cause any issues in practice,
even though we did not announce the removal of
`_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION` before.
---
 libcxx/docs/ReleaseNotes/19.rst               |   3 +-
 libcxx/docs/UsingLibcxx.rst                   |  12 --
 libcxx/include/__config                       |   2 -
 libcxx/include/__memory/allocator.h           |  16 +-
 ...xx2a.pass.cpp => address.cxx2a.verify.cpp} |  12 +-
 .../address.depr_in_cxx17.verify.cpp          |   4 +-
 .../allocator.members/allocate.cxx2a.pass.cpp |  93 -----------
 .../allocate.cxx2a.verify.cpp                 |   9 +-
 .../allocate.depr_in_cxx17.verify.cpp         |   4 +-
 .../construct.cxx2a.pass.cpp                  | 152 ------------------
 .../construct.cxx2a.verify.cpp                |  80 +++++++++
 ...x2a.pass.cpp => max_size.cxx2a.verify.cpp} |  10 +-
 .../allocator_types.cxx2a.pass.cpp            |  51 ------
 ...ed_allocator_members.deprecated.verify.cpp |  20 ---
 ...cxx20_allocator_void_no_members.verify.cpp |  25 ---
 ...xx20_with_removed_members.compile.pass.cpp |  22 ---
 .../containers/sequences/deque/types.pass.cpp |  17 +-
 .../containers/sequences/list/types.pass.cpp  |  11 +-
 .../sequences/vector/types.pass.cpp           |  17 +-
 19 files changed, 116 insertions(+), 444 deletions(-)
 rename libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/{address.cxx2a.pass.cpp => address.cxx2a.verify.cpp} (64%)
 delete mode 100644 libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.pass.cpp
 delete mode 100644 libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.pass.cpp
 create mode 100644 libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.verify.cpp
 rename libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/{max_size.cxx2a.pass.cpp => max_size.cxx2a.verify.cpp} (63%)
 delete mode 100644 libcxx/test/libcxx/depr/depr.default.allocator/allocator_types.cxx2a.pass.cpp
 delete mode 100644 libcxx/test/libcxx/depr/depr.default.allocator/enable_removed_allocator_members.deprecated.verify.cpp
 delete mode 100644 libcxx/test/libcxx/utilities/memory/default.allocator/allocator_types.void.cxx20_allocator_void_no_members.verify.cpp
 delete mode 100644 libcxx/test/libcxx/utilities/memory/default.allocator/allocator_types.void.cxx20_with_removed_members.compile.pass.cpp

diff --git a/libcxx/docs/ReleaseNotes/19.rst b/libcxx/docs/ReleaseNotes/19.rst
index c70ae477fafc1d..cac42f9c3c3f79 100644
--- a/libcxx/docs/ReleaseNotes/19.rst
+++ b/libcxx/docs/ReleaseNotes/19.rst
@@ -70,7 +70,8 @@ Deprecations and Removals
 - The ``_LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT`` macro that changed the behavior for narrowing conversions
   in ``std::variant`` has been removed in LLVM 19.
 
-- TODO: The ``_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS`` macro has been removed in LLVM 19.
+- The ``_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS`` and ``_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION``
+  macros have been removed in LLVM 19.
 
 - TODO: The ``_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES`` and ``_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES`` macros have
   been removed in LLVM 19. C++17 and C++20 removed features can still be re-enabled individually.
diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst
index 3b1be286c16981..ac12b0b9695079 100644
--- a/libcxx/docs/UsingLibcxx.rst
+++ b/libcxx/docs/UsingLibcxx.rst
@@ -244,18 +244,6 @@ C++20 Specific Configuration Macros
   This macro is deprecated and will be removed in LLVM-19. Use the
   individual macros listed below.
 
-**_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS**:
-  This macro is used to re-enable redundant members of `allocator<T>`,
-  including `pointer`, `reference`, `rebind`, `address`, `max_size`,
-  `construct`, `destroy`, and the two-argument overload of `allocate`.
-  This macro has been deprecated and will be removed in LLVM-19.
-
-**_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION**:
-  This macro is used to re-enable the library-provided specializations of
-  `allocator<void>` and `allocator<const void>`.
-  Use it in conjunction with `_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS`
-  to ensure that removed members of `allocator<void>` can be accessed.
-
 **_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS**:
   This macro is used to re-enable the `argument_type`, `result_type`,
   `first_argument_type`, and `second_argument_type` members of class
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 11e13e0c24986a..132cace3d5b2c4 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1238,8 +1238,6 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
 #  endif // _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES
 
 #  if defined(_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES)
-#    define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-#    define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION
 #    define _LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS
 #    define _LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS
 #    define _LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR
diff --git a/libcxx/include/__memory/allocator.h b/libcxx/include/__memory/allocator.h
index 4e6303914c38aa..26e5d4978b151e 100644
--- a/libcxx/include/__memory/allocator.h
+++ b/libcxx/include/__memory/allocator.h
@@ -31,18 +31,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 template <class _Tp>
 class allocator;
 
-#if defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
-#  pragma clang deprecated(                                                                                            \
-      _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS,                                                                  \
-      "_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS is deprecated in LLVM 18 and will be removed in LLVM 19")
-#endif
-
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION)
+#if _LIBCPP_STD_VER <= 17
 // These specializations shouldn't be marked _LIBCPP_DEPRECATED_IN_CXX17.
 // Specializing allocator<void> is deprecated, but not using it.
 template <>
 class _LIBCPP_TEMPLATE_VIS allocator<void> {
-#  if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
+#  if _LIBCPP_STD_VER <= 17
 
 public:
   _LIBCPP_DEPRECATED_IN_CXX17 typedef void* pointer;
@@ -58,7 +52,7 @@ class _LIBCPP_TEMPLATE_VIS allocator<void> {
 
 template <>
 class _LIBCPP_TEMPLATE_VIS allocator<const void> {
-#  if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
+#  if _LIBCPP_STD_VER <= 17
 
 public:
   _LIBCPP_DEPRECATED_IN_CXX17 typedef const void* pointer;
@@ -141,7 +135,7 @@ class _LIBCPP_TEMPLATE_VIS allocator : private __non_trivial_if<!is_void<_Tp>::v
   }
 
   // C++20 Removed members
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
+#if _LIBCPP_STD_VER <= 17
   _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp* pointer;
   _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
   _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp& reference;
@@ -221,7 +215,7 @@ class _LIBCPP_TEMPLATE_VIS allocator<const _Tp>
   }
 
   // C++20 Removed members
-#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
+#if _LIBCPP_STD_VER <= 17
   _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* pointer;
   _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
   _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& reference;
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx2a.pass.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx2a.verify.cpp
similarity index 64%
rename from libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx2a.pass.cpp
rename to libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx2a.verify.cpp
index 59657ca46a146d..b2ceba8fafef4d 100644
--- a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx2a.pass.cpp
+++ b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx2a.verify.cpp
@@ -12,12 +12,8 @@
 // pointer address(reference x) const;
 // const_pointer address(const_reference x) const;
 
-//  In C++20, parts of std::allocator<T> have been removed.
-//  However, for backwards compatibility, if _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-//  is defined before including <memory>, then removed members will be restored.
-
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+// In C++20, parts of std::allocator<T> have been removed.
+// UNSUPPORTED: c++03, c++11, c++14, c++17
 
 #include <memory>
 #include <cassert>
@@ -30,8 +26,8 @@ void test_address()
     T* tp = new T();
     const T* ctp = tp;
     const std::allocator<T> a;
-    assert(a.address(*tp) == tp);
-    assert(a.address(*ctp) == tp);
+    assert(a.address(*tp) == tp);  // expected-error 2 {{no member}}
+    assert(a.address(*ctp) == tp); // expected-error 2 {{no member}}
     delete tp;
 }
 
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.depr_in_cxx17.verify.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.depr_in_cxx17.verify.cpp
index 83d059a838ffb7..4098bdb2ee9252 100644
--- a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.depr_in_cxx17.verify.cpp
+++ b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.depr_in_cxx17.verify.cpp
@@ -14,9 +14,7 @@
 
 // Deprecated in C++17
 
-// UNSUPPORTED: c++03, c++11, c++14
-
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS -Wno-deprecated-pragma
+// REQUIRES: c++17
 
 #include <memory>
 
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.pass.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.pass.cpp
deleted file mode 100644
index f2fb606ee6dbcc..00000000000000
--- a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.pass.cpp
+++ /dev/null
@@ -1,93 +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
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// allocator:
-// T* allocate(size_t n, const void* hint);
-
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
-
-#include <memory>
-#include <cassert>
-#include <cstddef>       // for std::max_align_t
-
-#include "test_macros.h"
-#include "count_new.h"
-
-
-#ifdef TEST_HAS_NO_ALIGNED_ALLOCATION
-static const bool UsingAlignedNew = false;
-#else
-static const bool UsingAlignedNew = true;
-#endif
-
-#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
-static const std::size_t MaxAligned = __STDCPP_DEFAULT_NEW_ALIGNMENT__;
-#else
-static const std::size_t MaxAligned = std::alignment_of<std::max_align_t>::value;
-#endif
-
-static const std::size_t OverAligned = MaxAligned * 2;
-
-
-template <std::size_t Align>
-struct TEST_ALIGNAS(Align) AlignedType {
-  char data;
-  static int constructed;
-  AlignedType() { ++constructed; }
-  AlignedType(AlignedType const&) { ++constructed; }
-  ~AlignedType() { --constructed; }
-};
-template <std::size_t Align>
-int AlignedType<Align>::constructed = 0;
-
-
-template <std::size_t Align>
-void test_aligned() {
-  typedef AlignedType<Align> T;
-  T::constructed = 0;
-  globalMemCounter.reset();
-  std::allocator<T> a;
-  const bool IsOverAlignedType = Align > MaxAligned;
-  const bool ExpectAligned = IsOverAlignedType && UsingAlignedNew;
-  {
-    globalMemCounter.last_new_size = 0;
-    globalMemCounter.last_new_align = 0;
-    T* ap2 = a.allocate(11, (const void*)5);
-    DoNotOptimize(ap2);
-    assert(globalMemCounter.checkOutstandingNewEq(1));
-    assert(globalMemCounter.checkNewCalledEq(1));
-    assert(globalMemCounter.checkAlignedNewCalledEq(ExpectAligned));
-    assert(globalMemCounter.checkLastNewSizeEq(11 * sizeof(T)));
-    assert(globalMemCounter.checkLastNewAlignEq(ExpectAligned ? Align : 0));
-    assert(T::constructed == 0);
-    globalMemCounter.last_delete_align = 0;
-    a.deallocate(ap2, 11);
-    DoNotOptimize(ap2);
-    assert(globalMemCounter.checkOutstandingNewEq(0));
-    assert(globalMemCounter.checkDeleteCalledEq(1));
-    assert(globalMemCounter.checkAlignedDeleteCalledEq(ExpectAligned));
-    assert(globalMemCounter.checkLastDeleteAlignEq(ExpectAligned ? Align : 0));
-    assert(T::constructed == 0);
-  }
-}
-
-int main(int, char**) {
-    test_aligned<1>();
-    test_aligned<2>();
-    test_aligned<4>();
-    test_aligned<8>();
-    test_aligned<16>();
-    test_aligned<MaxAligned>();
-    test_aligned<OverAligned>();
-    test_aligned<OverAligned * 2>();
-
-  return 0;
-}
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.verify.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.verify.cpp
index 2289cd6cd40448..df6087344b6955 100644
--- a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.verify.cpp
+++ b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.verify.cpp
@@ -13,16 +13,11 @@
 // allocator:
 // T* allocate(size_t n, const void* hint);
 
-//  In C++20, parts of std::allocator<T> have been removed.
-//  However, for backwards compatibility, if _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-//  is defined before including <memory>, then removed members will be restored.
-
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+// Removed in C++20.
 
 #include <memory>
 
 void f() {
     std::allocator<int> a;
-    a.allocate(3, nullptr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+    a.allocate(3, nullptr); // expected-error {{too many arguments to function call}}
 }
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.depr_in_cxx17.verify.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.depr_in_cxx17.verify.cpp
index 8b2e862e9503e9..8629df3c41645b 100644
--- a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.depr_in_cxx17.verify.cpp
+++ b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.depr_in_cxx17.verify.cpp
@@ -13,9 +13,7 @@
 
 // Deprecated in C++17
 
-// UNSUPPORTED: c++03, c++11, c++14
-
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS -Wno-deprecated-pragma
+// REQUIRES: c++17
 
 #include <memory>
 
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.pass.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.pass.cpp
deleted file mode 100644
index d3a7dadbbe118c..00000000000000
--- a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.pass.cpp
+++ /dev/null
@@ -1,152 +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
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// allocator:
-// template <class... Args> void construct(pointer p, Args&&... args);
-
-//  In C++20, parts of std::allocator<T> have been removed.
-//  However, for backwards compatibility, if _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-//  is defined before including <memory>, then removed members will be restored.
-
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
-
-#include <memory>
-#include <cassert>
-
-#include "test_macros.h"
-#include "count_new.h"
-
-int A_constructed = 0;
-
-struct A
-{
-    int data;
-    A() {++A_constructed;}
-
-    A(const A&) {++A_constructed;}
-
-    explicit A(int) {++A_constructed;}
-    A(int, int*) {++A_constructed;}
-
-    ~A() {--A_constructed;}
-};
-
-int move_only_constructed = 0;
-
-#if TEST_STD_VER >= 11
-class move_only
-{
-    move_only(const move_only&) = delete;
-    move_only& operator=(const move_only&)= delete;
-
-public:
-    move_only(move_only&&) {++move_only_constructed;}
-    move_only& operator=(move_only&&) {return *this;}
-
-    move_only() {++move_only_constructed;}
-    ~move_only() {--move_only_constructed;}
-
-public:
-    int data; // unused other than to make sizeof(move_only) == sizeof(int).
-              // but public to suppress "-Wunused-private-field"
-};
-#endif // TEST_STD_VER >= 11
-
-int main(int, char**)
-{
-  globalMemCounter.reset();
-  {
-    std::allocator<A> a;
-    assert(globalMemCounter.checkOutstandingNewEq(0));
-    assert(A_constructed == 0);
-
-    globalMemCounter.last_new_size = 0;
-    A* ap = a.allocate(3);
-    DoNotOptimize(ap);
-    assert(globalMemCounter.checkOutstandingNewEq(1));
-    assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(int)));
-    assert(A_constructed == 0);
-
-    a.construct(ap);
-    assert(globalMemCounter.checkOutstandingNewEq(1));
-    assert(A_constructed == 1);
-
-    a.destroy(ap);
-    assert(globalMemCounter.checkOutstandingNewEq(1));
-    assert(A_constructed == 0);
-
-    a.construct(ap, A());
-    assert(globalMemCounter.checkOutstandingNewEq(1));
-    assert(A_constructed == 1);
-
-    a.destroy(ap);
-    assert(globalMemCounter.checkOutstandingNewEq(1));
-    assert(A_constructed == 0);
-
-    a.construct(ap, 5);
-    assert(globalMemCounter.checkOutstandingNewEq(1));
-    assert(A_constructed == 1);
-
-    a.destroy(ap);
-    assert(globalMemCounter.checkOutstandingNewEq(1));
-    assert(A_constructed == 0);
-
-    a.construct(ap, 5, (int*)0);
-    assert(globalMemCounter.checkOutstandingNewEq(1));
-    assert(A_constructed == 1);
-
-    a.destroy(ap);
-    assert(globalMemCounter.checkOutstandingNewEq(1));
-    assert(A_constructed == 0);
-
-    a.deallocate(ap, 3);
-    DoNotOptimize(ap);
-    assert(globalMemCounter.checkOutstandingNewEq(0));
-    assert(A_constructed == 0);
-  }
-#if TEST_STD_VER >= 11
-    {
-    std::allocator<move_only> a;
-    assert(globalMemCounter.checkOutstandingNewEq(0));
-    assert(move_only_constructed == 0);
-
-    globalMemCounter.last_new_size = 0;
-    move_only* ap = a.allocate(3);
-    DoNotOptimize(ap);
-    assert(globalMemCounter.checkOutstandingNewEq(1));
-    assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(int)));
-    assert(move_only_constructed == 0);
-
-    a.construct(ap);
-    assert(globalMemCounter.checkOutstandingNewEq(1));
-    assert(move_only_constructed == 1);
-
-    a.destroy(ap);
-    assert(globalMemCounter.checkOutstandingNewEq(1));
-    assert(move_only_constructed == 0);
-
-    a.construct(ap, move_only());
-    assert(globalMemCounter.checkOutstandingNewEq(1));
-    assert(move_only_constructed == 1);
-
-    a.destroy(ap);
-    assert(globalMemCounter.checkOutstandingNewEq(1));
-    assert(move_only_constructed == 0);
-
-    a.deallocate(ap, 3);
-    DoNotOptimize(ap);
-    assert(globalMemCounter.checkOutstandingNewEq(0));
-    assert(move_only_constructed == 0);
-    }
-#endif
-
-  return 0;
-}
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.verify.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.verify.cpp
new file mode 100644
index 00000000000000..f4ff536d47a2ea
--- /dev/null
+++ b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.verify.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// allocator:
+// template <class... Args> void construct(pointer p, Args&&... args);
+
+// Removed in C++20.
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+#include <memory>
+#include <cassert>
+
+int A_constructed = 0;
+
+struct A
+{
+    int data;
+    A() {++A_constructed;}
+
+    A(const A&) {++A_constructed;}
+
+    explicit A(int) {++A_constructed;}
+    A(int, int*) {++A_constructed;}
+
+    ~A() {--A_constructed;}
+};
+
+int move_only_constructed = 0;
+
+class move_only
+{
+    move_only(const move_only&) = delete;
+    move_only& operator=(const move_only&)= delete;
+
+public:
+    move_only(move_only&&) {++move_only_constructed;}
+    move_only& operator=(move_only&&) {return *this;}
+
+    move_only() {++move_only_constructed;}
+    ~move_only() {--move_only_constructed;}
+
+public:
+    int data; // unused other than to make sizeof(move_only) == sizeof(int).
+              // but public to suppress "-Wunused-private-field"
+};
+
+int main(int, char**)
+{
+  {
+    std::allocator<A> a;
+    A* ap = a.allocate(3);
+    a.construct(ap); // expected-error {{no member}}
+    a.destroy(ap); // expected-error {{no member}}
+    a.construct(ap, A()); // expected-error {{no member}}
+    a.destroy(ap); // expected-error {{no member}}
+    a.construct(ap, 5); // expected-error {{no member}}
+    a.destroy(ap); // expected-error {{no member}}
+    a.construct(ap, 5, (int*)0); // expected-error {{no member}}
+    a.destroy(ap); // expected-error {{no member}}
+    a.deallocate(ap, 3);
+  }
+    {
+    std::allocator<move_only> a;
+    move_only* ap = a.allocate(3);
+    a.construct(ap); // expected-error {{no member}}
+    a.destroy(ap); // expected-error {{no member}}
+    a.construct(ap, move_only()); // expected-error {{no member}}
+    a.destroy(ap); // expected-error {{no member}}
+    a.deallocate(ap, 3);
+    }
+  return 0;
+}
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx2a.pass.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx2a.verify.cpp
similarity index 63%
rename from libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx2a.pass.cpp
rename to libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx2a.verify.cpp
index b07568355fee76..9455ed65aeb5e1 100644
--- a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx2a.pass.cpp
+++ b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx2a.verify.cpp
@@ -11,12 +11,8 @@
 // allocator:
 // size_type max_size() const throw();
 
-//  In C++20, parts of std::allocator<T> have been removed.
-//  However, for backwards compatibility, if _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-//  is defined before including <memory>, then removed members will be restored.
-
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+// In C++20, parts of std::allocator<T> have been removed.
+// UNSUPPORTED: c++03, c++11, c++14, c++17
 
 #include <memory>
 #include <limits>
@@ -30,7 +26,7 @@ int new_called = 0;
 int main(int, char**)
 {
     const std::allocator<int> a;
-    std::size_t M = a.max_size();
+    std::size_t M = a.max_size(); // expected-error {{no member}}
     assert(M > 0xFFFF && M <= (std::numeric_limits<std::size_t>::max() / sizeof(int)));
 
   return 0;
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator_types.cxx2a.pass.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator_types.cxx2a.pass.cpp
deleted file mode 100644
index a6134b04a8f555..00000000000000
--- a/libcxx/test/libcxx/depr/depr.default.allocator/allocator_types.cxx2a.pass.cpp
+++ /dev/null
@@ -1,51 +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
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// Check that the following types are provided regardless of the Standard when
-// we request them from libc++.
-
-// template <class T>
-// class allocator
-// {
-// public:
-//     typedef size_t                                size_type;
-//     typedef ptrdiff_t                             difference_type;
-//     typedef T*                                    pointer;
-//     typedef const T*                              const_pointer;
-//     typedef typename add_lvalue_reference<T>::type       reference;
-//     typedef typename add_lvalue_reference<const T>::type const_reference;
-//
-//     template <class U> struct rebind {typedef allocator<U> other;};
-// ...
-// };
-
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
-
-#include <memory>
-#include <type_traits>
-#include <cstddef>
-
-template <class T>
-void test() {
-    static_assert((std::is_same<typename std::allocator<T>::size_type, std::size_t>::value), "");
-    static_assert((std::is_same<typename std::allocator<T>::difference_type, std::ptrdiff_t>::value), "");
-    static_assert((std::is_same<typename std::allocator<T>::pointer, T*>::value), "");
-    static_assert((std::is_same<typename std::allocator<T>::const_pointer, const T*>::value), "");
-    static_assert((std::is_same<typename std::allocator<T>::reference, T&>::value), "");
-    static_assert((std::is_same<typename std::allocator<T>::const_reference, const T&>::value), "");
-    static_assert((std::is_same<typename std::allocator<T>::template rebind<int>::other,
-                                std::allocator<int> >::value), "");
-}
-
-int main(int, char**) {
-    test<char>();
-    return 0;
-}
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/enable_removed_allocator_members.deprecated.verify.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/enable_removed_allocator_members.deprecated.verify.cpp
deleted file mode 100644
index ab6495ea9db47c..00000000000000
--- a/libcxx/test/libcxx/depr/depr.default.allocator/enable_removed_allocator_members.deprecated.verify.cpp
+++ /dev/null
@@ -1,20 +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
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// Ensure that defining _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS yields a
-// deprecation warning. We intend to issue a deprecation warning in LLVM 18
-// and remove the macro entirely in LLVM 19. As such, this test will be quite
-// short lived.
-
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-
-// UNSUPPORTED: clang-modules-build
-
-#include <memory> // expected-warning@* 1+ {{macro '_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS' has been marked as deprecated}}
diff --git a/libcxx/test/libcxx/utilities/memory/default.allocator/allocator_types.void.cxx20_allocator_void_no_members.verify.cpp b/libcxx/test/libcxx/utilities/memory/default.allocator/allocator_types.void.cxx20_allocator_void_no_members.verify.cpp
deleted file mode 100644
index 8888683a044f27..00000000000000
--- a/libcxx/test/libcxx/utilities/memory/default.allocator/allocator_types.void.cxx20_allocator_void_no_members.verify.cpp
+++ /dev/null
@@ -1,25 +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
-//
-//===----------------------------------------------------------------------===//
-
-// Check that members of std::allocator<void> are not provided in C++20
-// with _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION but without
-// _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS.
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION
-//
-// Ignore any extra errors arising from typo correction.
-// ADDITIONAL_COMPILE_FLAGS: -Xclang -verify-ignore-unexpected=error
-
-#include <memory>
-
-std::allocator<void>::pointer x;            // expected-error-re {{no {{(type|template)}} named 'pointer'}}
-std::allocator<void>::const_pointer y;      // expected-error-re {{no {{(type|template)}} named 'const_pointer'}}
-std::allocator<void>::value_type z;         // expected-error-re {{no {{(type|template)}} named 'value_type'}}
-std::allocator<void>::rebind<int>::other t; // expected-error-re {{no {{(type|template)}} named 'rebind'}}
diff --git a/libcxx/test/libcxx/utilities/memory/default.allocator/allocator_types.void.cxx20_with_removed_members.compile.pass.cpp b/libcxx/test/libcxx/utilities/memory/default.allocator/allocator_types.void.cxx20_with_removed_members.compile.pass.cpp
deleted file mode 100644
index 3f151edefe1cdc..00000000000000
--- a/libcxx/test/libcxx/utilities/memory/default.allocator/allocator_types.void.cxx20_with_removed_members.compile.pass.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
-//
-//===----------------------------------------------------------------------===//
-
-// Check that the nested types of std::allocator<void> are provided in C++20
-// with a flag that keeps the removed members.
-
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION
-
-#include <memory>
-#include <type_traits>
-
-static_assert((std::is_same<std::allocator<void>::pointer, void*>::value), "");
-static_assert((std::is_same<std::allocator<void>::const_pointer, const void*>::value), "");
-static_assert((std::is_same<std::allocator<void>::value_type, void>::value), "");
-static_assert((std::is_same<std::allocator<void>::rebind<int>::other, std::allocator<int> >::value), "");
diff --git a/libcxx/test/std/containers/sequences/deque/types.pass.cpp b/libcxx/test/std/containers/sequences/deque/types.pass.cpp
index bfe4808f863d3e..ceb024180186a0 100644
--- a/libcxx/test/std/containers/sequences/deque/types.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/types.pass.cpp
@@ -28,9 +28,6 @@
 //     typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
 // };
 
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
-
 #include <deque>
 #include <iterator>
 #include <type_traits>
@@ -47,14 +44,14 @@ test()
     typedef std::deque<T, Allocator> C;
 
     static_assert((std::is_same<typename C::value_type, T>::value), "");
-    static_assert((std::is_same<typename C::value_type, typename Allocator::value_type>::value), "");
+    static_assert((std::is_same<typename C::value_type, typename std::allocator_traits<Allocator>::value_type>::value), "");
     static_assert((std::is_same<typename C::allocator_type, Allocator>::value), "");
-    static_assert((std::is_same<typename C::size_type, typename Allocator::size_type>::value), "");
-    static_assert((std::is_same<typename C::difference_type, typename Allocator::difference_type>::value), "");
-    static_assert((std::is_same<typename C::reference, typename Allocator::reference>::value), "");
-    static_assert((std::is_same<typename C::const_reference, typename Allocator::const_reference>::value), "");
-    static_assert((std::is_same<typename C::pointer, typename Allocator::pointer>::value), "");
-    static_assert((std::is_same<typename C::const_pointer, typename Allocator::const_pointer>::value), "");
+    static_assert((std::is_same<typename C::size_type, typename std::allocator_traits<Allocator>::size_type>::value), "");
+    static_assert((std::is_same<typename C::difference_type, typename std::allocator_traits<Allocator>::difference_type>::value), "");
+    static_assert((std::is_same<typename C::reference, typename std::allocator_traits<Allocator>::value_type&>::value), "");
+    static_assert((std::is_same<typename C::const_reference, const typename std::allocator_traits<Allocator>::value_type&>::value), "");
+    static_assert((std::is_same<typename C::pointer, typename std::allocator_traits<Allocator>::pointer>::value), "");
+    static_assert((std::is_same<typename C::const_pointer, typename std::allocator_traits<Allocator>::const_pointer>::value), "");
     static_assert((std::is_same<
         typename std::iterator_traits<typename C::iterator>::iterator_category,
         std::random_access_iterator_tag>::value), "");
diff --git a/libcxx/test/std/containers/sequences/list/types.pass.cpp b/libcxx/test/std/containers/sequences/list/types.pass.cpp
index 0c1ca27745ce0e..323f0a3057a894 100644
--- a/libcxx/test/std/containers/sequences/list/types.pass.cpp
+++ b/libcxx/test/std/containers/sequences/list/types.pass.cpp
@@ -21,9 +21,6 @@
 //     typedef typename allocator_type::pointer pointer;
 //     typedef typename allocator_type::const_pointer const_pointer;
 
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
-
 #include <list>
 #include <type_traits>
 
@@ -38,10 +35,10 @@ int main(int, char**)
     typedef std::list<int> C;
     static_assert((std::is_same<C::value_type, int>::value), "");
     static_assert((std::is_same<C::allocator_type, std::allocator<int> >::value), "");
-    static_assert((std::is_same<C::reference, std::allocator<int>::reference>::value), "");
-    static_assert((std::is_same<C::const_reference, std::allocator<int>::const_reference>::value), "");
-    static_assert((std::is_same<C::pointer, std::allocator<int>::pointer>::value), "");
-    static_assert((std::is_same<C::const_pointer, std::allocator<int>::const_pointer>::value), "");
+    static_assert((std::is_same<C::reference, std::allocator_traits<std::allocator<int>>::value_type&>::value), "");
+    static_assert((std::is_same<C::const_reference, const std::allocator_traits<std::allocator<int>>::value_type&>::value), "");
+    static_assert((std::is_same<C::pointer, std::allocator_traits<std::allocator<int>>::pointer>::value), "");
+    static_assert((std::is_same<C::const_pointer, std::allocator_traits<std::allocator<int>>::const_pointer>::value), "");
 
     static_assert((std::is_signed<typename C::difference_type>::value), "");
     static_assert((std::is_unsigned<typename C::size_type>::value), "");
diff --git a/libcxx/test/std/containers/sequences/vector/types.pass.cpp b/libcxx/test/std/containers/sequences/vector/types.pass.cpp
index 4bcfbe7c3ea4d4..e1db70a8062e20 100644
--- a/libcxx/test/std/containers/sequences/vector/types.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/types.pass.cpp
@@ -28,9 +28,6 @@
 //     typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
 // };
 
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
-// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
-
 #include <vector>
 #include <iterator>
 #include <type_traits>
@@ -52,14 +49,14 @@ test()
 //  blindly pulling typedefs out of the allocator. This is why we can't call
 //  test<int, min_allocator<int>>() below.
     static_assert((std::is_same<typename C::value_type, T>::value), "");
-    static_assert((std::is_same<typename C::value_type, typename Allocator::value_type>::value), "");
+    static_assert((std::is_same<typename C::value_type, typename std::allocator_traits<Allocator>::value_type>::value), "");
     static_assert((std::is_same<typename C::allocator_type, Allocator>::value), "");
-    static_assert((std::is_same<typename C::size_type, typename Allocator::size_type>::value), "");
-    static_assert((std::is_same<typename C::difference_type, typename Allocator::difference_type>::value), "");
-    static_assert((std::is_same<typename C::reference, typename Allocator::reference>::value), "");
-    static_assert((std::is_same<typename C::const_reference, typename Allocator::const_reference>::value), "");
-    static_assert((std::is_same<typename C::pointer, typename Allocator::pointer>::value), "");
-    static_assert((std::is_same<typename C::const_pointer, typename Allocator::const_pointer>::value), "");
+    static_assert((std::is_same<typename C::size_type, typename std::allocator_traits<Allocator>::size_type>::value), "");
+    static_assert((std::is_same<typename C::difference_type, typename std::allocator_traits<Allocator>::difference_type>::value), "");
+    static_assert((std::is_same<typename C::reference, typename std::allocator_traits<Allocator>::value_type&>::value), "");
+    static_assert((std::is_same<typename C::const_reference, const typename std::allocator_traits<Allocator>::value_type&>::value), "");
+    static_assert((std::is_same<typename C::pointer, typename std::allocator_traits<Allocator>::pointer>::value), "");
+    static_assert((std::is_same<typename C::const_pointer, typename std::allocator_traits<Allocator>::const_pointer>::value), "");
 
     static_assert((std::is_signed<typename C::difference_type>::value), "");
     static_assert((std::is_unsigned<typename C::size_type>::value), "");

>From ab8a6a79f03bf533e40d8d6f14cd44db110125c0 Mon Sep 17 00:00:00 2001
From: Ilya Biryukov <ibiryukov at google.com>
Date: Wed, 20 Mar 2024 19:13:16 +0100
Subject: [PATCH 2/3] fixup! [libc++] Remove macros for keeping std::allocator
 members and void specialization after C++20

Restore removed files, make them run only in pre-C++20 modes.
---
 .../allocator.members/address.cxx2a.pass.cpp  |  47 ++++++
 .../allocator.members/allocate.cxx2a.pass.cpp |  95 +++++++++++
 .../construct.cxx2a.pass.cpp                  | 150 ++++++++++++++++++
 .../allocator.members/max_size.cxx2a.pass.cpp |  35 ++++
 .../allocator_types.cxx2a.pass.cpp            |  53 +++++++
 5 files changed, 380 insertions(+)
 create mode 100644 libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx2a.pass.cpp
 create mode 100644 libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.pass.cpp
 create mode 100644 libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.pass.cpp
 create mode 100644 libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx2a.pass.cpp
 create mode 100644 libcxx/test/libcxx/depr/depr.default.allocator/allocator_types.cxx2a.pass.cpp

diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx2a.pass.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx2a.pass.cpp
new file mode 100644
index 00000000000000..2530aa8b5acded
--- /dev/null
+++ b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx2a.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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// allocator:
+// pointer address(reference x) const;
+// const_pointer address(const_reference x) const;
+
+// Removed in C++20, deprecated in C++17.
+
+// REQUIRES: c++03 || c++11 || c++14 || c++17
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+
+template <class T>
+void test_address()
+{
+    T* tp = new T();
+    const T* ctp = tp;
+    const std::allocator<T> a;
+    assert(a.address(*tp) == tp);
+    assert(a.address(*ctp) == tp);
+    delete tp;
+}
+
+struct A
+{
+    void operator&() const {}
+};
+
+int main(int, char**)
+{
+    test_address<int>();
+    test_address<A>();
+
+  return 0;
+}
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.pass.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.pass.cpp
new file mode 100644
index 00000000000000..8e3b4298e2ddee
--- /dev/null
+++ b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.pass.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// allocator:
+// T* allocate(size_t n, const void* hint);
+
+// Removed in C++20, deprecated in C++17.
+
+// REQUIRES: c++03 || c++11 || c++14 || c++17
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+#include <memory>
+#include <cassert>
+#include <cstddef>       // for std::max_align_t
+
+#include "test_macros.h"
+#include "count_new.h"
+
+
+#ifdef TEST_HAS_NO_ALIGNED_ALLOCATION
+static const bool UsingAlignedNew = false;
+#else
+static const bool UsingAlignedNew = true;
+#endif
+
+#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
+static const std::size_t MaxAligned = __STDCPP_DEFAULT_NEW_ALIGNMENT__;
+#else
+static const std::size_t MaxAligned = std::alignment_of<std::max_align_t>::value;
+#endif
+
+static const std::size_t OverAligned = MaxAligned * 2;
+
+
+template <std::size_t Align>
+struct TEST_ALIGNAS(Align) AlignedType {
+  char data;
+  static int constructed;
+  AlignedType() { ++constructed; }
+  AlignedType(AlignedType const&) { ++constructed; }
+  ~AlignedType() { --constructed; }
+};
+template <std::size_t Align>
+int AlignedType<Align>::constructed = 0;
+
+
+template <std::size_t Align>
+void test_aligned() {
+  typedef AlignedType<Align> T;
+  T::constructed = 0;
+  globalMemCounter.reset();
+  std::allocator<T> a;
+  const bool IsOverAlignedType = Align > MaxAligned;
+  const bool ExpectAligned = IsOverAlignedType && UsingAlignedNew;
+  {
+    globalMemCounter.last_new_size = 0;
+    globalMemCounter.last_new_align = 0;
+    T* ap2 = a.allocate(11, (const void*)5);
+    DoNotOptimize(ap2);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(globalMemCounter.checkNewCalledEq(1));
+    assert(globalMemCounter.checkAlignedNewCalledEq(ExpectAligned));
+    assert(globalMemCounter.checkLastNewSizeEq(11 * sizeof(T)));
+    assert(globalMemCounter.checkLastNewAlignEq(ExpectAligned ? Align : 0));
+    assert(T::constructed == 0);
+    globalMemCounter.last_delete_align = 0;
+    a.deallocate(ap2, 11);
+    DoNotOptimize(ap2);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
+    assert(globalMemCounter.checkDeleteCalledEq(1));
+    assert(globalMemCounter.checkAlignedDeleteCalledEq(ExpectAligned));
+    assert(globalMemCounter.checkLastDeleteAlignEq(ExpectAligned ? Align : 0));
+    assert(T::constructed == 0);
+  }
+}
+
+int main(int, char**) {
+    test_aligned<1>();
+    test_aligned<2>();
+    test_aligned<4>();
+    test_aligned<8>();
+    test_aligned<16>();
+    test_aligned<MaxAligned>();
+    test_aligned<OverAligned>();
+    test_aligned<OverAligned * 2>();
+
+  return 0;
+}
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.pass.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.pass.cpp
new file mode 100644
index 00000000000000..6f4355c5a5adc3
--- /dev/null
+++ b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.pass.cpp
@@ -0,0 +1,150 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// allocator:
+// template <class... Args> void construct(pointer p, Args&&... args);
+
+// In C++20, parts of std::allocator<T> have been removed.
+// In C++17, they were deprecated.
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+// REQUIRES: c++03 || c++11 || c++14 || c++17
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+#include "count_new.h"
+
+int A_constructed = 0;
+
+struct A
+{
+    int data;
+    A() {++A_constructed;}
+
+    A(const A&) {++A_constructed;}
+
+    explicit A(int) {++A_constructed;}
+    A(int, int*) {++A_constructed;}
+
+    ~A() {--A_constructed;}
+};
+
+int move_only_constructed = 0;
+
+#if TEST_STD_VER >= 11
+class move_only
+{
+    move_only(const move_only&) = delete;
+    move_only& operator=(const move_only&)= delete;
+
+public:
+    move_only(move_only&&) {++move_only_constructed;}
+    move_only& operator=(move_only&&) {return *this;}
+
+    move_only() {++move_only_constructed;}
+    ~move_only() {--move_only_constructed;}
+
+public:
+    int data; // unused other than to make sizeof(move_only) == sizeof(int).
+              // but public to suppress "-Wunused-private-field"
+};
+#endif // TEST_STD_VER >= 11
+
+int main(int, char**)
+{
+  globalMemCounter.reset();
+  {
+    std::allocator<A> a;
+    assert(globalMemCounter.checkOutstandingNewEq(0));
+    assert(A_constructed == 0);
+
+    globalMemCounter.last_new_size = 0;
+    A* ap = a.allocate(3);
+    DoNotOptimize(ap);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(int)));
+    assert(A_constructed == 0);
+
+    a.construct(ap);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(A_constructed == 1);
+
+    a.destroy(ap);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(A_constructed == 0);
+
+    a.construct(ap, A());
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(A_constructed == 1);
+
+    a.destroy(ap);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(A_constructed == 0);
+
+    a.construct(ap, 5);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(A_constructed == 1);
+
+    a.destroy(ap);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(A_constructed == 0);
+
+    a.construct(ap, 5, (int*)0);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(A_constructed == 1);
+
+    a.destroy(ap);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(A_constructed == 0);
+
+    a.deallocate(ap, 3);
+    DoNotOptimize(ap);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
+    assert(A_constructed == 0);
+  }
+#if TEST_STD_VER >= 11
+    {
+    std::allocator<move_only> a;
+    assert(globalMemCounter.checkOutstandingNewEq(0));
+    assert(move_only_constructed == 0);
+
+    globalMemCounter.last_new_size = 0;
+    move_only* ap = a.allocate(3);
+    DoNotOptimize(ap);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(globalMemCounter.checkLastNewSizeEq(3 * sizeof(int)));
+    assert(move_only_constructed == 0);
+
+    a.construct(ap);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(move_only_constructed == 1);
+
+    a.destroy(ap);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(move_only_constructed == 0);
+
+    a.construct(ap, move_only());
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(move_only_constructed == 1);
+
+    a.destroy(ap);
+    assert(globalMemCounter.checkOutstandingNewEq(1));
+    assert(move_only_constructed == 0);
+
+    a.deallocate(ap, 3);
+    DoNotOptimize(ap);
+    assert(globalMemCounter.checkOutstandingNewEq(0));
+    assert(move_only_constructed == 0);
+    }
+#endif
+
+  return 0;
+}
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx2a.pass.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx2a.pass.cpp
new file mode 100644
index 00000000000000..891a7e7a8b7aec
--- /dev/null
+++ b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx2a.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// allocator:
+// size_type max_size() const throw();
+
+// Removed in C++20, deprecated in C++17.
+
+// REQUIRES: c++03 || c++11 || c++14 || c++17
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+#include <memory>
+#include <limits>
+#include <cstddef>
+#include <cassert>
+
+#include "test_macros.h"
+
+int new_called = 0;
+
+int main(int, char**)
+{
+    const std::allocator<int> a;
+    std::size_t M = a.max_size();
+    assert(M > 0xFFFF && M <= (std::numeric_limits<std::size_t>::max() / sizeof(int)));
+
+  return 0;
+}
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator_types.cxx2a.pass.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator_types.cxx2a.pass.cpp
new file mode 100644
index 00000000000000..5246041be66111
--- /dev/null
+++ b/libcxx/test/libcxx/depr/depr.default.allocator/allocator_types.cxx2a.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
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// Check that the following types are provided regardless of the Standard when
+// we request them from libc++.
+
+// template <class T>
+// class allocator
+// {
+// public:
+//     typedef size_t                                size_type;
+//     typedef ptrdiff_t                             difference_type;
+//     typedef T*                                    pointer;
+//     typedef const T*                              const_pointer;
+//     typedef typename add_lvalue_reference<T>::type       reference;
+//     typedef typename add_lvalue_reference<const T>::type const_reference;
+//
+//     template <class U> struct rebind {typedef allocator<U> other;};
+// ...
+// };
+
+// Removed in C++20, deprecated in C++17.
+
+// REQUIRES: c++03 || c++11 || c++14 || c++17
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
+#include <memory>
+#include <type_traits>
+#include <cstddef>
+
+template <class T>
+void test() {
+    static_assert((std::is_same<typename std::allocator<T>::size_type, std::size_t>::value), "");
+    static_assert((std::is_same<typename std::allocator<T>::difference_type, std::ptrdiff_t>::value), "");
+    static_assert((std::is_same<typename std::allocator<T>::pointer, T*>::value), "");
+    static_assert((std::is_same<typename std::allocator<T>::const_pointer, const T*>::value), "");
+    static_assert((std::is_same<typename std::allocator<T>::reference, T&>::value), "");
+    static_assert((std::is_same<typename std::allocator<T>::const_reference, const T&>::value), "");
+    static_assert((std::is_same<typename std::allocator<T>::template rebind<int>::other,
+                                std::allocator<int> >::value), "");
+}
+
+int main(int, char**) {
+    test<char>();
+    return 0;
+}

>From 200158611af7a042f83717ee204c3b093c197d52 Mon Sep 17 00:00:00 2001
From: Ilya Biryukov <ibiryukov at google.com>
Date: Wed, 20 Mar 2024 19:22:38 +0100
Subject: [PATCH 3/3] fixup! [libc++] Remove macros for keeping std::allocator
 members and void specialization after C++20

Rename files from cxx2a to cxx20.
---
 .../{address.cxx2a.pass.cpp => address.cxx20.pass.cpp}            | 0
 .../{address.cxx2a.verify.cpp => address.cxx20.verify.cpp}        | 0
 .../{allocate.cxx2a.pass.cpp => allocate.cxx20.pass.cpp}          | 0
 .../{allocate.cxx2a.verify.cpp => allocate.cxx20.verify.cpp}      | 0
 .../{construct.cxx2a.pass.cpp => construct.cxx20.pass.cpp}        | 0
 .../{construct.cxx2a.verify.cpp => construct.cxx20.verify.cpp}    | 0
 .../{max_size.cxx2a.pass.cpp => max_size.cxx20.pass.cpp}          | 0
 .../{max_size.cxx2a.verify.cpp => max_size.cxx20.verify.cpp}      | 0
 ...ocator_types.cxx2a.pass.cpp => allocator_types.cxx20.pass.cpp} | 0
 9 files changed, 0 insertions(+), 0 deletions(-)
 rename libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/{address.cxx2a.pass.cpp => address.cxx20.pass.cpp} (100%)
 rename libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/{address.cxx2a.verify.cpp => address.cxx20.verify.cpp} (100%)
 rename libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/{allocate.cxx2a.pass.cpp => allocate.cxx20.pass.cpp} (100%)
 rename libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/{allocate.cxx2a.verify.cpp => allocate.cxx20.verify.cpp} (100%)
 rename libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/{construct.cxx2a.pass.cpp => construct.cxx20.pass.cpp} (100%)
 rename libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/{construct.cxx2a.verify.cpp => construct.cxx20.verify.cpp} (100%)
 rename libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/{max_size.cxx2a.pass.cpp => max_size.cxx20.pass.cpp} (100%)
 rename libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/{max_size.cxx2a.verify.cpp => max_size.cxx20.verify.cpp} (100%)
 rename libcxx/test/libcxx/depr/depr.default.allocator/{allocator_types.cxx2a.pass.cpp => allocator_types.cxx20.pass.cpp} (100%)

diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx2a.pass.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx20.pass.cpp
similarity index 100%
rename from libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx2a.pass.cpp
rename to libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx20.pass.cpp
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx2a.verify.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx20.verify.cpp
similarity index 100%
rename from libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx2a.verify.cpp
rename to libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx20.verify.cpp
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.pass.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx20.pass.cpp
similarity index 100%
rename from libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.pass.cpp
rename to libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx20.pass.cpp
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.verify.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx20.verify.cpp
similarity index 100%
rename from libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.verify.cpp
rename to libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx20.verify.cpp
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.pass.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx20.pass.cpp
similarity index 100%
rename from libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.pass.cpp
rename to libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx20.pass.cpp
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.verify.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx20.verify.cpp
similarity index 100%
rename from libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.verify.cpp
rename to libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx20.verify.cpp
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx2a.pass.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx20.pass.cpp
similarity index 100%
rename from libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx2a.pass.cpp
rename to libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx20.pass.cpp
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx2a.verify.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx20.verify.cpp
similarity index 100%
rename from libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx2a.verify.cpp
rename to libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx20.verify.cpp
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator_types.cxx2a.pass.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator_types.cxx20.pass.cpp
similarity index 100%
rename from libcxx/test/libcxx/depr/depr.default.allocator/allocator_types.cxx2a.pass.cpp
rename to libcxx/test/libcxx/depr/depr.default.allocator/allocator_types.cxx20.pass.cpp



More information about the libcxx-commits mailing list