Skip to content

[libc++] Remove macros for keeping std::allocator members and void specialization after C++20 #85806

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 21, 2024

Conversation

ilya-biryukov
Copy link
Contributor

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.

…ecialization after C++20

Fixes llvm#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.
@ilya-biryukov ilya-biryukov added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Mar 19, 2024
@ilya-biryukov ilya-biryukov requested a review from ldionne March 19, 2024 15:43
@ilya-biryukov ilya-biryukov requested a review from a team as a code owner March 19, 2024 15:43
@llvmbot
Copy link
Member

llvmbot commented Mar 19, 2024

@llvm/pr-subscribers-libcxx

Author: Ilya Biryukov (ilya-biryukov)

Changes

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.


Patch is 35.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/85806.diff

19 Files Affected:

  • (modified) libcxx/docs/ReleaseNotes/19.rst (+2-1)
  • (modified) libcxx/docs/UsingLibcxx.rst (-12)
  • (modified) libcxx/include/__config (-2)
  • (modified) libcxx/include/__memory/allocator.h (+5-11)
  • (renamed) libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.cxx2a.verify.cpp (+4-8)
  • (modified) libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/address.depr_in_cxx17.verify.cpp (+1-3)
  • (removed) libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.pass.cpp (-93)
  • (modified) libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.cxx2a.verify.cpp (+2-7)
  • (modified) libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/allocate.depr_in_cxx17.verify.cpp (+1-3)
  • (removed) libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.pass.cpp (-152)
  • (added) libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/construct.cxx2a.verify.cpp (+80)
  • (renamed) libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/max_size.cxx2a.verify.cpp (+3-7)
  • (removed) libcxx/test/libcxx/depr/depr.default.allocator/allocator_types.cxx2a.pass.cpp (-51)
  • (removed) libcxx/test/libcxx/depr/depr.default.allocator/enable_removed_allocator_members.deprecated.verify.cpp (-20)
  • (removed) libcxx/test/libcxx/utilities/memory/default.allocator/allocator_types.void.cxx20_allocator_void_no_members.verify.cpp (-25)
  • (removed) libcxx/test/libcxx/utilities/memory/default.allocator/allocator_types.void.cxx20_with_removed_members.compile.pass.cpp (-22)
  • (modified) libcxx/test/std/containers/sequences/deque/types.pass.cpp (+7-10)
  • (modified) libcxx/test/std/containers/sequences/list/types.pass.cpp (+4-7)
  • (modified) libcxx/test/std/containers/sequences/vector/types.pass.cpp (+7-10)
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.me...
[truncated]

Copy link

github-actions bot commented Mar 19, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@ilya-biryukov
Copy link
Contributor Author

Please let me know if removal of _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION in this patch is controversial. I can see why someone would want to go with a more conservative approach (e.g. deprecate it in LLVM 19 and remove in LLVM 20), although my proposal would be to remove it right away. Happy to update this PR to go the other way.

I would also like to get feedback on the test updates as I wasn't sure I was taking all the right turns there.

Copy link
Contributor

@philnik777 philnik777 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but let's wait for Louis.

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for picking up this task, I really appreciate it! I have some questions but it's probably just me missing the point, this patch looks good overall.

…void specialization after C++20

Restore removed files, make them run only in pre-C++20 modes.
…void specialization after C++20

Rename files from cxx2a to cxx20.
@ilya-biryukov
Copy link
Contributor Author

Thanks a lot for picking up this task, I really appreciate it! I have some questions but it's probably just me missing the point, this patch looks good overall.

Thanks for a quick review and an insightful comment. I think I did remove some useful tests, it was unintentional, I had some wrong assumptions about the tests that I didn't check. They should be restored now.

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM w/ green CI and clang-format. Thanks!

…void specialization after C++20

Add spaces between consequtive right angle brackets.
…void specialization after C++20

clang-format the patch
@ilya-biryukov ilya-biryukov merged commit 4bf8dc1 into llvm:main Mar 21, 2024
@ilya-biryukov ilya-biryukov deleted the allocator_members branch March 22, 2024 09:20
chencha3 pushed a commit to chencha3/llvm-project that referenced this pull request Mar 23, 2024
…ecialization after C++20 (llvm#85806)

Fixes llvm#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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[libc++] Remove the _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS escape hatch
4 participants