[libcxx-commits] [libcxx] [libcxx] Make removed allocator members constexpr in C++20 (PR #69466)

Ilya Biryukov via libcxx-commits libcxx-commits at lists.llvm.org
Wed Oct 18 08:36:51 PDT 2023


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

>From faad8b688f673cb2cdb4d431d69e27c6a1bc05d4 Mon Sep 17 00:00:00 2001
From: Ilya Biryukov <ibiryukov at google.com>
Date: Wed, 18 Oct 2023 15:56:55 +0200
Subject: [PATCH 1/2] [libcxx] Make removed allocator members constexpr in
 C++20

With `-D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS`, restored
allocator members were non-constexpr. This led to `vector` and `string`
being non-`constexpr` too.

This change makes sure the library types stay `constexpr` even in this
backwards-compatibile mode.
---
 libcxx/include/__memory/allocator.h           | 15 +++----
 .../constexpr.cxx2a.verify.cpp                | 42 +++++++++++++++++++
 2 files changed, 50 insertions(+), 7 deletions(-)
 create mode 100644 libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/constexpr.cxx2a.verify.cpp

diff --git a/libcxx/include/__memory/allocator.h b/libcxx/include/__memory/allocator.h
index 47e1ef926a4afe4..3b51984012b7d70 100644
--- a/libcxx/include/__memory/allocator.h
+++ b/libcxx/include/__memory/allocator.h
@@ -152,23 +152,24 @@ class _LIBCPP_TEMPLATE_VIS allocator
         return _VSTD::addressof(__x);
     }
 
-    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
-    _Tp* allocate(size_t __n, const void*) {
+    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
+        _Tp*
+        allocate(size_t __n, const void*) {
         return allocate(__n);
     }
 
-    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {
+    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_INLINE_VISIBILITY size_type
+    max_size() const _NOEXCEPT {
         return size_type(~0) / sizeof(_Tp);
     }
 
     template <class _Up, class... _Args>
-    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
-    void construct(_Up* __p, _Args&&... __args) {
+    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_INLINE_VISIBILITY void
+    construct(_Up* __p, _Args&&... __args) {
         ::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
     }
 
-    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
-    void destroy(pointer __p) {
+    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {
         __p->~_Tp();
     }
 #endif
diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/constexpr.cxx2a.verify.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/constexpr.cxx2a.verify.cpp
new file mode 100644
index 000000000000000..52b76e81ab69b9f
--- /dev/null
+++ b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/constexpr.cxx2a.verify.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// 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>
+
+//  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.
+
+//  This leads to `vector` and `string` using those members instead of `allocator_traits`.
+//  So the restored members must also be made `constexpr` to make sure instantiated members
+//  of those types stay `constexpr`.
+
+//  Check that the necessary members, vector and string can be used as constants in this mode.
+
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+// expected-no-diagnostics
+
+#include <memory>
+#include <vector>
+#include <string>
+
+static_assert(std::allocator<int>().max_size() != 0);
+
+constexpr int check_lifetime_return_123() {
+  std::allocator<int> a;
+  int* p = a.allocate(10);
+  a.construct(p, 1);
+  a.destroy(p);
+  a.deallocate(p, 10);
+  return 123;
+}
+static_assert(check_lifetime_return_123() == 123);
+
+static_assert(std::vector<int>({1, 2, 3}).size() == 3);
+static_assert(std::string("abc").size() == 3);

>From 0d0299a484fd4d2e1ce51b096d9ed41d7b9991fb Mon Sep 17 00:00:00 2001
From: Ilya Biryukov <ibiryukov at google.com>
Date: Wed, 18 Oct 2023 17:35:51 +0200
Subject: [PATCH 2/2] fixup! [libcxx] Make removed allocator members constexpr
 in C++20

Mark builds modes before C++20 as unsupported
---
 .../allocator.members/constexpr.cxx2a.verify.cpp                 | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/constexpr.cxx2a.verify.cpp b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/constexpr.cxx2a.verify.cpp
index 52b76e81ab69b9f..24f70d1afe6a683 100644
--- a/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/constexpr.cxx2a.verify.cpp
+++ b/libcxx/test/libcxx/depr/depr.default.allocator/allocator.members/constexpr.cxx2a.verify.cpp
@@ -18,6 +18,7 @@
 
 //  Check that the necessary members, vector and string can be used as constants in this mode.
 
+// UNSUPPORTED: c++03, c++11, c++14, c++17
 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
 // expected-no-diagnostics



More information about the libcxx-commits mailing list