Skip to content

Commit 400b33e

Browse files
committed
[libc++] Disallow volatile types in std::allocator
LWG 2447 is marked as `Complete`, but there is no `static_assert` to reject volatile types in `std::allocator`. See the discussion at https://reviews.llvm.org/D108856. Add `static_assert` in `std::allocator` to disallow volatile types. Since this is an implementation choice, mark the binding test as `libc++` only. Remove tests that use containers backed by `std::allocator` that test the container when used with a volatile type. Reviewed By: ldionne, #libc Differential Revision: https://reviews.llvm.org/D109056
1 parent ca999f7 commit 400b33e

File tree

6 files changed

+42
-69
lines changed

6 files changed

+42
-69
lines changed

libcxx/TODO.TXT

-1
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,3 @@ Misc Tasks
2121
* Find all sequences of >2 underscores and eradicate them.
2222
* run clang-tidy on libc++
2323
* Document the "conditionally-supported" bits of libc++
24-
* Put a static_assert in std::allocator to deny const/volatile types (LWG 2447)

libcxx/include/__memory/allocator.h

+2
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ template <class _Tp>
8080
class _LIBCPP_TEMPLATE_VIS allocator
8181
: private __non_trivial_if<!is_void<_Tp>::value, allocator<_Tp> >
8282
{
83+
static_assert(!is_volatile<_Tp>::value, "std::allocator does not support volatile types");
8384
public:
8485
typedef size_t size_type;
8586
typedef ptrdiff_t difference_type;
@@ -162,6 +163,7 @@ template <class _Tp>
162163
class _LIBCPP_TEMPLATE_VIS allocator<const _Tp>
163164
: private __non_trivial_if<!is_void<_Tp>::value, allocator<const _Tp> >
164165
{
166+
static_assert(!is_volatile<_Tp>::value, "std::allocator does not support volatile types");
165167
public:
166168
typedef size_t size_type;
167169
typedef ptrdiff_t difference_type;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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+
// REQUIRES: libc++
10+
11+
// http://wg21.link/LWG2447 gives implementors freedom to reject volatile types in `std::allocator`.
12+
13+
#include <memory>
14+
15+
std::allocator<volatile int> A1; // expected-error@*:* {{std::allocator does not support volatile types}}
16+
std::allocator<const volatile int> A2; // expected-error@*:* {{std::allocator does not support volatile types}}

libcxx/test/std/concepts/concepts.lang/concept.default.init/default_initializable.compile.pass.cpp

-4
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,6 @@ void test()
204204
test_true <std::deque< int>>();
205205
#ifdef _LIBCPP_VERSION
206206
test_true <std::deque<const int>>();
207-
test_true <std::deque< volatile int>>();
208-
test_true <std::deque<const volatile int>>();
209207
#endif // _LIBCPP_VERSION
210208
test_true <std::forward_list<int>>();
211209
test_true <std::list<int>>();
@@ -227,8 +225,6 @@ void test()
227225
test_true <std::stack< int>>();
228226
#ifdef _LIBCPP_VERSION
229227
test_true <std::stack<const int>>();
230-
test_true <std::stack< volatile int>>();
231-
test_true <std::stack<const volatile int>>();
232228
#endif // _LIBCPP_VERSION
233229
test_true <std::queue<int>>();
234230
test_true <std::priority_queue<int>>();

libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,26 @@ void test_pointer_to_function() {
7373
void test_pointer_to_function() {}
7474
#endif // _LIBCPP_VERSION
7575

76+
template <typename T>
77+
void test(const T &t0)
78+
{
79+
{
80+
T t1 = t0;
81+
std::shared_ptr<T> p0 = std::make_shared<T>(t0);
82+
std::shared_ptr<T> p1 = std::make_shared<T>(t1);
83+
assert(*p0 == t0);
84+
assert(*p1 == t1);
85+
}
86+
87+
{
88+
const T t1 = t0;
89+
std::shared_ptr<const T> p0 = std::make_shared<const T>(t0);
90+
std::shared_ptr<const T> p1 = std::make_shared<const T>(t1);
91+
assert(*p0 == t0);
92+
assert(*p1 == t1);
93+
}
94+
}
95+
7696
int main(int, char**)
7797
{
7898
int nc = globalMemCounter.outstanding_new;
@@ -108,5 +128,9 @@ int main(int, char**)
108128
#endif
109129
assert(A::count == 0);
110130

131+
test<bool>(true);
132+
test<int>(3);
133+
test<double>(5.0);
134+
111135
return 0;
112136
}

libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.volatile.pass.cpp

-64
This file was deleted.

0 commit comments

Comments
 (0)