Skip to content

Commit 87784cc

Browse files
committed
[libc++] Undeprecate the std::allocator<void> specialization
While the std::allocator<void> specialization was deprecated by https://wg21.link/p0174#2.2, the *use* of std::allocator<void> by users was not. The intent was that std::allocator<void> could still be used in C++17 and C++20, but starting with C++20 (with the removal of the specialization), std::allocator<void> would use the primary template. That intent was called out in wg21.link/p0619r4#3.9. As a result of this patch, _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS will also not control whether the explicit specialization is provided or not. It shouldn't matter, since in C++20, one can simply use the primary template. Fixes http://llvm.org/PR50299 Differential Revision: https://reviews.llvm.org/D104323
1 parent 70b37f4 commit 87784cc

13 files changed

+133
-139
lines changed

libcxx/docs/UsingLibcxx.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,6 @@ C++20 Specific Configuration Macros:
253253
This macro is used to re-enable redundant members of `allocator<T>`,
254254
including `pointer`, `reference`, `rebind`, `address`, `max_size`,
255255
`construct`, `destroy`, and the two-argument overload of `allocate`.
256-
It also re-enables the library-provided explicit specializations
257-
of `allocator<void>` and `allocator<const void>`.
258256

259257
**_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS**:
260258
This macro is used to re-enable the `argument_type`, `result_type`,

libcxx/include/__memory/allocator.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,27 +28,27 @@ _LIBCPP_BEGIN_NAMESPACE_STD
2828

2929
template <class _Tp> class allocator;
3030

31-
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
31+
#if _LIBCPP_STD_VER <= 17
3232
template <>
33-
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 allocator<void>
33+
class _LIBCPP_TEMPLATE_VIS allocator<void>
3434
{
3535
public:
36-
typedef void* pointer;
37-
typedef const void* const_pointer;
38-
typedef void value_type;
36+
_LIBCPP_DEPRECATED_IN_CXX17 typedef void* pointer;
37+
_LIBCPP_DEPRECATED_IN_CXX17 typedef const void* const_pointer;
38+
_LIBCPP_DEPRECATED_IN_CXX17 typedef void value_type;
3939

40-
template <class _Up> struct rebind {typedef allocator<_Up> other;};
40+
template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;};
4141
};
4242

4343
template <>
44-
class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 allocator<const void>
44+
class _LIBCPP_TEMPLATE_VIS allocator<const void>
4545
{
4646
public:
47-
typedef const void* pointer;
48-
typedef const void* const_pointer;
49-
typedef const void value_type;
47+
_LIBCPP_DEPRECATED_IN_CXX17 typedef const void* pointer;
48+
_LIBCPP_DEPRECATED_IN_CXX17 typedef const void* const_pointer;
49+
_LIBCPP_DEPRECATED_IN_CXX17 typedef const void value_type;
5050

51-
template <class _Up> struct rebind {typedef allocator<_Up> other;};
51+
template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;};
5252
};
5353
#endif
5454

libcxx/include/memory

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ struct allocator_traits
9999
};
100100
101101
template <>
102-
class allocator<void> // deprecated in C++17, removed in C++20
102+
class allocator<void> // removed in C++20
103103
{
104104
public:
105105
typedef void* pointer;

libcxx/test/libcxx/depr/depr.default.allocator/allocator_types.cxx2a.pass.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,19 @@
3333
#include <type_traits>
3434
#include <cstddef>
3535

36-
#include "test_macros.h"
37-
38-
int main(int, char**)
39-
{
40-
static_assert((std::is_same<std::allocator<char>::size_type, std::size_t>::value), "");
41-
static_assert((std::is_same<std::allocator<char>::difference_type, std::ptrdiff_t>::value), "");
42-
static_assert((std::is_same<std::allocator<char>::pointer, char*>::value), "");
43-
static_assert((std::is_same<std::allocator<char>::const_pointer, const char*>::value), "");
44-
static_assert((std::is_same<std::allocator<char>::reference, char&>::value), "");
45-
static_assert((std::is_same<std::allocator<char>::const_reference, const char&>::value), "");
46-
static_assert((std::is_same<std::allocator<char>::rebind<int>::other,
36+
template <class T>
37+
void test() {
38+
static_assert((std::is_same<typename std::allocator<T>::size_type, std::size_t>::value), "");
39+
static_assert((std::is_same<typename std::allocator<T>::difference_type, std::ptrdiff_t>::value), "");
40+
static_assert((std::is_same<typename std::allocator<T>::pointer, T*>::value), "");
41+
static_assert((std::is_same<typename std::allocator<T>::const_pointer, const T*>::value), "");
42+
static_assert((std::is_same<typename std::allocator<T>::reference, T&>::value), "");
43+
static_assert((std::is_same<typename std::allocator<T>::const_reference, const T&>::value), "");
44+
static_assert((std::is_same<typename std::allocator<T>::template rebind<int>::other,
4745
std::allocator<int> >::value), "");
46+
}
4847

48+
int main(int, char**) {
49+
test<char>();
4950
return 0;
5051
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
// <memory>
10+
11+
// Make sure we can use std::allocator<void> in all Standard modes. While the
12+
// explicit specialization for std::allocator<void> was deprecated, using that
13+
// specialization was neither deprecated nor removed (in C++20 it should simply
14+
// start using the primary template).
15+
//
16+
// See https://llvm.org/PR50299.
17+
18+
#include <memory>
19+
20+
std::allocator<void> a;

libcxx/test/std/utilities/memory/default.allocator/allocator.ctor.pass.cpp

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@
77
//===----------------------------------------------------------------------===//
88

99
// <memory>
10-
// UNSUPPORTED: c++03, c++11, c++14, c++17
1110
//
1211
// template <class T>
1312
// class allocator
1413
// {
1514
// public: // All of these are constexpr after C++17
16-
// constexpr allocator() noexcept;
17-
// constexpr allocator(const allocator&) noexcept;
18-
// template<class U> constexpr allocator(const allocator<U>&) noexcept;
15+
// allocator() noexcept;
16+
// allocator(const allocator&) noexcept;
17+
// template<class U> allocator(const allocator<U>&) noexcept;
1918
// ...
2019
// };
2120

@@ -24,28 +23,27 @@
2423

2524
#include "test_macros.h"
2625

26+
template<class T>
27+
TEST_CONSTEXPR_CXX20 bool test() {
28+
typedef std::allocator<T> A1;
29+
typedef std::allocator<long> A2;
2730

28-
int main(int, char**)
29-
{
30-
{
31-
typedef std::allocator<char> AC;
32-
typedef std::allocator<long> AL;
31+
A1 a1;
32+
A1 a1_copy = a1; (void)a1_copy;
33+
A2 a2 = a1; (void)a2;
3334

34-
constexpr AC a1;
35-
constexpr AC a2{a1};
36-
constexpr AL a3{a2};
37-
(void) a3;
38-
}
39-
{
40-
typedef std::allocator<const char> AC;
41-
typedef std::allocator<const long> AL;
42-
43-
constexpr AC a1;
44-
constexpr AC a2{a1};
45-
constexpr AL a3{a2};
46-
(void) a3;
47-
}
35+
return true;
36+
}
4837

38+
int main(int, char**) {
39+
test<char>();
40+
test<char const>();
41+
test<void>();
4942

43+
#if TEST_STD_VER > 17
44+
static_assert(test<char>());
45+
static_assert(test<char const>());
46+
static_assert(test<void>());
47+
#endif
5048
return 0;
5149
}

libcxx/test/std/utilities/memory/default.allocator/allocator.dtor.pass.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
#include <memory>
1515

16-
1716
template <typename T>
1817
constexpr bool test() {
1918
std::allocator<T> alloc;
@@ -26,11 +25,13 @@ constexpr bool test() {
2625
int main(int, char**)
2726
{
2827
test<int>();
28+
test<void>();
2929
#ifdef _LIBCPP_VERSION // extension
3030
test<int const>();
3131
#endif // _LIBCPP_VERSION
3232

3333
static_assert(test<int>());
34+
static_assert(test<void>());
3435
#ifdef _LIBCPP_VERSION // extension
3536
static_assert(test<int const>());
3637
#endif // _LIBCPP_VERSION

libcxx/test/std/utilities/memory/default.allocator/allocator_pointers.pass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
#include <memory>
1212
#include <cassert>
1313

14-
// #include <memory>
15-
1614
#include "test_macros.h"
15+
16+
// <memory>
1717
//
1818
// template <class Alloc>
1919
// struct allocator_traits

libcxx/test/std/utilities/memory/default.allocator/allocator_types.deprecated_in_cxx17.verify.cpp

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,27 @@
3030
// UNSUPPORTED: clang-6
3131

3232
#include <memory>
33-
#include "test_macros.h"
3433

35-
int main(int, char**)
36-
{
37-
typedef std::allocator<char>::pointer AP; // expected-warning {{'pointer' is deprecated}}
38-
typedef std::allocator<char>::const_pointer ACP; // expected-warning {{'const_pointer' is deprecated}}
39-
typedef std::allocator<char>::reference AR; // expected-warning {{'reference' is deprecated}}
40-
typedef std::allocator<char>::const_reference ACR; // expected-warning {{'const_reference' is deprecated}}
41-
typedef std::allocator<char>::rebind<int>::other ARO; // expected-warning {{'rebind<int>' is deprecated}}
42-
43-
typedef std::allocator<char const>::pointer AP2; // expected-warning {{'pointer' is deprecated}}
44-
typedef std::allocator<char const>::const_pointer ACP2; // expected-warning {{'const_pointer' is deprecated}}
45-
typedef std::allocator<char const>::reference AR2; // expected-warning {{'reference' is deprecated}}
46-
typedef std::allocator<char const>::const_reference ACR2; // expected-warning {{'const_reference' is deprecated}}
47-
typedef std::allocator<char const>::rebind<int>::other ARO2; // expected-warning {{'rebind<int>' is deprecated}}
34+
int main(int, char**) {
35+
{
36+
typedef std::allocator<char>::pointer Pointer; // expected-warning {{'pointer' is deprecated}}
37+
typedef std::allocator<char>::const_pointer ConstPointer; // expected-warning {{'const_pointer' is deprecated}}
38+
typedef std::allocator<char>::reference Reference; // expected-warning {{'reference' is deprecated}}
39+
typedef std::allocator<char>::const_reference ConstReference; // expected-warning {{'const_reference' is deprecated}}
40+
typedef std::allocator<char>::rebind<int>::other Rebind; // expected-warning {{'rebind<int>' is deprecated}}
41+
}
42+
{
43+
typedef std::allocator<char const>::pointer Pointer; // expected-warning {{'pointer' is deprecated}}
44+
typedef std::allocator<char const>::const_pointer ConstPointer; // expected-warning {{'const_pointer' is deprecated}}
45+
typedef std::allocator<char const>::reference Reference; // expected-warning {{'reference' is deprecated}}
46+
typedef std::allocator<char const>::const_reference ConstReference; // expected-warning {{'const_reference' is deprecated}}
47+
typedef std::allocator<char const>::rebind<int>::other Rebind; // expected-warning {{'rebind<int>' is deprecated}}
48+
}
49+
{
50+
typedef std::allocator<void>::pointer Pointer; // expected-warning {{'pointer' is deprecated}}
51+
typedef std::allocator<void>::const_pointer ConstPointer; // expected-warning {{'const_pointer' is deprecated}}
52+
// reference and const_reference are not provided by std::allocator<void>
53+
typedef std::allocator<void>::rebind<int>::other Rebind; // expected-warning {{'rebind<int>' is deprecated}}
54+
}
4855
return 0;
4956
}

libcxx/test/std/utilities/memory/default.allocator/allocator_types.pass.cpp

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,47 +18,49 @@
1818
// typedef ptrdiff_t difference_type;
1919
// typedef T value_type;
2020
//
21+
// typedef T* pointer; // deprecated in C++17, removed in C++20
22+
// typedef T const* const_pointer; // deprecated in C++17, removed in C++20
23+
// typedef T& reference; // deprecated in C++17, removed in C++20
24+
// typedef T const& const_reference; // deprecated in C++17, removed in C++20
25+
// template< class U > struct rebind { typedef allocator<U> other; }; // deprecated in C++17, removed in C++20
26+
//
2127
// typedef true_type propagate_on_container_move_assignment;
2228
// typedef true_type is_always_equal;
2329
// ...
2430
// };
2531

32+
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
33+
2634
#include <memory>
2735
#include <type_traits>
2836
#include <cstddef>
2937

3038
#include "test_macros.h"
3139

32-
template <typename T, typename U>
33-
TEST_CONSTEXPR_CXX20 bool test()
34-
{
35-
static_assert((std::is_same<typename std::allocator<T>::size_type, std::size_t>::value), "");
36-
static_assert((std::is_same<typename std::allocator<T>::difference_type, std::ptrdiff_t>::value), "");
37-
static_assert((std::is_same<typename std::allocator<T>::value_type, T>::value), "");
38-
static_assert((std::is_same<typename std::allocator<T>::propagate_on_container_move_assignment, std::true_type>::value), "");
39-
static_assert((std::is_same<typename std::allocator<T>::is_always_equal, std::true_type>::value), "");
40+
struct U;
4041

41-
std::allocator<T> a;
42-
std::allocator<T> a2 = a;
43-
a2 = a;
44-
std::allocator<U> a3 = a2;
45-
(void)a3;
42+
template <typename T>
43+
void test() {
44+
typedef std::allocator<T> Alloc;
45+
static_assert((std::is_same<typename Alloc::size_type, std::size_t>::value), "");
46+
static_assert((std::is_same<typename Alloc::difference_type, std::ptrdiff_t>::value), "");
47+
static_assert((std::is_same<typename Alloc::value_type, T>::value), "");
48+
static_assert((std::is_same<typename Alloc::propagate_on_container_move_assignment, std::true_type>::value), "");
49+
static_assert((std::is_same<typename Alloc::is_always_equal, std::true_type>::value), "");
4650

47-
return true;
51+
#if TEST_STD_VER <= 17
52+
static_assert((std::is_same<typename Alloc::pointer, T*>::value), "");
53+
static_assert((std::is_same<typename Alloc::const_pointer, T const*>::value), "");
54+
static_assert((std::is_same<typename Alloc::reference, T&>::value), "");
55+
static_assert((std::is_same<typename Alloc::const_reference, T const&>::value), "");
56+
static_assert((std::is_same<typename Alloc::template rebind<U>::other, std::allocator<U> >::value), "");
57+
#endif
4858
}
4959

50-
int main(int, char**)
51-
{
52-
test<char, int>();
53-
#ifdef _LIBCPP_VERSION // extension
54-
test<char const, int const>();
55-
#endif // _LIBCPP_VERSION
56-
57-
#if TEST_STD_VER > 17
58-
static_assert(test<char, int>());
59-
#ifdef _LIBCPP_VERSION // extension
60-
static_assert(test<char const, int const>());
61-
#endif // _LIBCPP_VERSION
60+
int main(int, char**) {
61+
test<char>();
62+
#ifdef _LIBCPP_VERSION
63+
test<char const>(); // extension
6264
#endif
6365
return 0;
6466
}

0 commit comments

Comments
 (0)