[libcxx-commits] [libcxx] 374f938 - [libcxx] Fix allocator<void>::pointer in C++20 with removed members

Ilya Biryukov via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jun 15 01:56:17 PDT 2022


Author: Ilya Biryukov
Date: 2022-06-15T10:55:56+02:00
New Revision: 374f938fe8f2beefbac8de9faf5d79fea8469e3d

URL: https://github.com/llvm/llvm-project/commit/374f938fe8f2beefbac8de9faf5d79fea8469e3d
DIFF: https://github.com/llvm/llvm-project/commit/374f938fe8f2beefbac8de9faf5d79fea8469e3d.diff

LOG: [libcxx] Fix allocator<void>::pointer in C++20 with removed members

When compiled with `-D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS`
uses of `allocator<void>::pointer` resulted in compiler errors after D104323.
If we instantiate the primary template, `allocator<void>::reference` produces
an error 'cannot form references to void'.

To workaround this, allow to bring back the `allocator<void>` specialization by defining the new `_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION` macro.

To make sure the code that uses `allocator<void>` and the removed members does not break,
both `_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS` and `_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS` have to be defined.

Reviewed By: ldionne, #libc, philnik

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

Added: 
    libcxx/test/libcxx/utilities/memory/default.allocator/allocator_types.void.cxx20_allocator_void_no_members.verify.cpp
    libcxx/test/libcxx/utilities/memory/default.allocator/allocator_types.void.cxx20_with_removed_members.compile.pass.cpp

Modified: 
    libcxx/docs/ReleaseNotes.rst
    libcxx/docs/UsingLibcxx.rst
    libcxx/include/__config
    libcxx/include/__memory/allocator.h

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst
index 362e0cedbb77c..bae9567893d25 100644
--- a/libcxx/docs/ReleaseNotes.rst
+++ b/libcxx/docs/ReleaseNotes.rst
@@ -136,6 +136,11 @@ API Changes
   against the static version of libc++, which will result in no dependency being
   taken against the shared library.
 
+- The ``_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION`` macro has been added to allow
+  re-enabling the ``allocator<void>`` specialization. When used in conjuction with
+  ``_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS``, this ensures that the members of
+  ``allocator<void>`` removed in C++20 can be accessed.
+
 ABI Changes
 -----------
 

diff  --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst
index 55dbb363fe73d..f2bed0d407e2a 100644
--- a/libcxx/docs/UsingLibcxx.rst
+++ b/libcxx/docs/UsingLibcxx.rst
@@ -314,6 +314,12 @@ C++20 Specific Configuration Macros:
   including `pointer`, `reference`, `rebind`, `address`, `max_size`,
   `construct`, `destroy`, and the two-argument overload of `allocate`.
 
+**_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 a8f84de50fb48..6303f63ff1115 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1152,6 +1152,7 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(const
 
 #  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 1945848674f22..118b95469f3eb 100644
--- a/libcxx/include/__memory/allocator.h
+++ b/libcxx/include/__memory/allocator.h
@@ -27,27 +27,31 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp> class allocator;
 
-#if _LIBCPP_STD_VER <= 17
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION)
 template <>
 class _LIBCPP_TEMPLATE_VIS allocator<void>
 {
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
 public:
     _LIBCPP_DEPRECATED_IN_CXX17 typedef void*             pointer;
     _LIBCPP_DEPRECATED_IN_CXX17 typedef const void*       const_pointer;
     _LIBCPP_DEPRECATED_IN_CXX17 typedef void              value_type;
 
     template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;};
+#endif
 };
 
 template <>
 class _LIBCPP_TEMPLATE_VIS allocator<const void>
 {
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
 public:
     _LIBCPP_DEPRECATED_IN_CXX17 typedef const void*       pointer;
     _LIBCPP_DEPRECATED_IN_CXX17 typedef const void*       const_pointer;
     _LIBCPP_DEPRECATED_IN_CXX17 typedef const void        value_type;
 
     template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;};
+#endif
 };
 #endif
 

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
new file mode 100644
index 0000000000000..8888683a044f2
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/memory/default.allocator/allocator_types.void.cxx20_allocator_void_no_members.verify.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
new file mode 100644
index 0000000000000..3f151edefe1cd
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/memory/default.allocator/allocator_types.void.cxx20_with_removed_members.compile.pass.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// 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), "");


        


More information about the libcxx-commits mailing list