Skip to content

Commit 374f938

Browse files
committed
[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
1 parent 1784fe7 commit 374f938

File tree

6 files changed

+64
-1
lines changed

6 files changed

+64
-1
lines changed

libcxx/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ API Changes
136136
against the static version of libc++, which will result in no dependency being
137137
taken against the shared library.
138138

139+
- The ``_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION`` macro has been added to allow
140+
re-enabling the ``allocator<void>`` specialization. When used in conjuction with
141+
``_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS``, this ensures that the members of
142+
``allocator<void>`` removed in C++20 can be accessed.
143+
139144
ABI Changes
140145
-----------
141146

libcxx/docs/UsingLibcxx.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,12 @@ C++20 Specific Configuration Macros:
314314
including `pointer`, `reference`, `rebind`, `address`, `max_size`,
315315
`construct`, `destroy`, and the two-argument overload of `allocate`.
316316

317+
**_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION**:
318+
This macro is used to re-enable the library-provided specializations of
319+
`allocator<void>` and `allocator<const void>`.
320+
Use it in conjunction with `_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS`
321+
to ensure that removed members of `allocator<void>` can be accessed.
322+
317323
**_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS**:
318324
This macro is used to re-enable the `argument_type`, `result_type`,
319325
`first_argument_type`, and `second_argument_type` members of class

libcxx/include/__config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,7 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(const
11521152

11531153
# if defined(_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES)
11541154
# define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
1155+
# define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION
11551156
# define _LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS
11561157
# define _LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS
11571158
# define _LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR

libcxx/include/__memory/allocator.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,31 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2727

2828
template <class _Tp> class allocator;
2929

30-
#if _LIBCPP_STD_VER <= 17
30+
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION)
3131
template <>
3232
class _LIBCPP_TEMPLATE_VIS allocator<void>
3333
{
34+
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
3435
public:
3536
_LIBCPP_DEPRECATED_IN_CXX17 typedef void* pointer;
3637
_LIBCPP_DEPRECATED_IN_CXX17 typedef const void* const_pointer;
3738
_LIBCPP_DEPRECATED_IN_CXX17 typedef void value_type;
3839

3940
template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;};
41+
#endif
4042
};
4143

4244
template <>
4345
class _LIBCPP_TEMPLATE_VIS allocator<const void>
4446
{
47+
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
4548
public:
4649
_LIBCPP_DEPRECATED_IN_CXX17 typedef const void* pointer;
4750
_LIBCPP_DEPRECATED_IN_CXX17 typedef const void* const_pointer;
4851
_LIBCPP_DEPRECATED_IN_CXX17 typedef const void value_type;
4952

5053
template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;};
54+
#endif
5155
};
5256
#endif
5357

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// Check that members of std::allocator<void> are not provided in C++20
10+
// with _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION but without
11+
// _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS.
12+
13+
// UNSUPPORTED: c++03, c++11, c++14, c++17
14+
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
15+
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION
16+
//
17+
// Ignore any extra errors arising from typo correction.
18+
// ADDITIONAL_COMPILE_FLAGS: -Xclang -verify-ignore-unexpected=error
19+
20+
#include <memory>
21+
22+
std::allocator<void>::pointer x; // expected-error-re {{no {{(type|template)}} named 'pointer'}}
23+
std::allocator<void>::const_pointer y; // expected-error-re {{no {{(type|template)}} named 'const_pointer'}}
24+
std::allocator<void>::value_type z; // expected-error-re {{no {{(type|template)}} named 'value_type'}}
25+
std::allocator<void>::rebind<int>::other t; // expected-error-re {{no {{(type|template)}} named 'rebind'}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// Check that the nested types of std::allocator<void> are provided in C++20
10+
// with a flag that keeps the removed members.
11+
12+
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
13+
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS
14+
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION
15+
16+
#include <memory>
17+
#include <type_traits>
18+
19+
static_assert((std::is_same<std::allocator<void>::pointer, void*>::value), "");
20+
static_assert((std::is_same<std::allocator<void>::const_pointer, const void*>::value), "");
21+
static_assert((std::is_same<std::allocator<void>::value_type, void>::value), "");
22+
static_assert((std::is_same<std::allocator<void>::rebind<int>::other, std::allocator<int> >::value), "");

0 commit comments

Comments
 (0)