forked from OSchip/llvm-project
[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
This commit is contained in:
parent
ca999f7191
commit
400b33e18d
|
@ -21,4 +21,3 @@ Misc Tasks
|
||||||
* Find all sequences of >2 underscores and eradicate them.
|
* Find all sequences of >2 underscores and eradicate them.
|
||||||
* run clang-tidy on libc++
|
* run clang-tidy on libc++
|
||||||
* Document the "conditionally-supported" bits of libc++
|
* Document the "conditionally-supported" bits of libc++
|
||||||
* Put a static_assert in std::allocator to deny const/volatile types (LWG 2447)
|
|
||||||
|
|
|
@ -80,6 +80,7 @@ template <class _Tp>
|
||||||
class _LIBCPP_TEMPLATE_VIS allocator
|
class _LIBCPP_TEMPLATE_VIS allocator
|
||||||
: private __non_trivial_if<!is_void<_Tp>::value, allocator<_Tp> >
|
: private __non_trivial_if<!is_void<_Tp>::value, allocator<_Tp> >
|
||||||
{
|
{
|
||||||
|
static_assert(!is_volatile<_Tp>::value, "std::allocator does not support volatile types");
|
||||||
public:
|
public:
|
||||||
typedef size_t size_type;
|
typedef size_t size_type;
|
||||||
typedef ptrdiff_t difference_type;
|
typedef ptrdiff_t difference_type;
|
||||||
|
@ -162,6 +163,7 @@ template <class _Tp>
|
||||||
class _LIBCPP_TEMPLATE_VIS allocator<const _Tp>
|
class _LIBCPP_TEMPLATE_VIS allocator<const _Tp>
|
||||||
: private __non_trivial_if<!is_void<_Tp>::value, allocator<const _Tp> >
|
: private __non_trivial_if<!is_void<_Tp>::value, allocator<const _Tp> >
|
||||||
{
|
{
|
||||||
|
static_assert(!is_volatile<_Tp>::value, "std::allocator does not support volatile types");
|
||||||
public:
|
public:
|
||||||
typedef size_t size_type;
|
typedef size_t size_type;
|
||||||
typedef ptrdiff_t difference_type;
|
typedef ptrdiff_t difference_type;
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// REQUIRES: libc++
|
||||||
|
|
||||||
|
// http://wg21.link/LWG2447 gives implementors freedom to reject volatile types in `std::allocator`.
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
std::allocator<volatile int> A1; // expected-error@*:* {{std::allocator does not support volatile types}}
|
||||||
|
std::allocator<const volatile int> A2; // expected-error@*:* {{std::allocator does not support volatile types}}
|
|
@ -204,8 +204,6 @@ void test()
|
||||||
test_true <std::deque< int>>();
|
test_true <std::deque< int>>();
|
||||||
#ifdef _LIBCPP_VERSION
|
#ifdef _LIBCPP_VERSION
|
||||||
test_true <std::deque<const int>>();
|
test_true <std::deque<const int>>();
|
||||||
test_true <std::deque< volatile int>>();
|
|
||||||
test_true <std::deque<const volatile int>>();
|
|
||||||
#endif // _LIBCPP_VERSION
|
#endif // _LIBCPP_VERSION
|
||||||
test_true <std::forward_list<int>>();
|
test_true <std::forward_list<int>>();
|
||||||
test_true <std::list<int>>();
|
test_true <std::list<int>>();
|
||||||
|
@ -227,8 +225,6 @@ void test()
|
||||||
test_true <std::stack< int>>();
|
test_true <std::stack< int>>();
|
||||||
#ifdef _LIBCPP_VERSION
|
#ifdef _LIBCPP_VERSION
|
||||||
test_true <std::stack<const int>>();
|
test_true <std::stack<const int>>();
|
||||||
test_true <std::stack< volatile int>>();
|
|
||||||
test_true <std::stack<const volatile int>>();
|
|
||||||
#endif // _LIBCPP_VERSION
|
#endif // _LIBCPP_VERSION
|
||||||
test_true <std::queue<int>>();
|
test_true <std::queue<int>>();
|
||||||
test_true <std::priority_queue<int>>();
|
test_true <std::priority_queue<int>>();
|
||||||
|
|
|
@ -73,6 +73,26 @@ void test_pointer_to_function() {
|
||||||
void test_pointer_to_function() {}
|
void test_pointer_to_function() {}
|
||||||
#endif // _LIBCPP_VERSION
|
#endif // _LIBCPP_VERSION
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void test(const T &t0)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
T t1 = t0;
|
||||||
|
std::shared_ptr<T> p0 = std::make_shared<T>(t0);
|
||||||
|
std::shared_ptr<T> p1 = std::make_shared<T>(t1);
|
||||||
|
assert(*p0 == t0);
|
||||||
|
assert(*p1 == t1);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const T t1 = t0;
|
||||||
|
std::shared_ptr<const T> p0 = std::make_shared<const T>(t0);
|
||||||
|
std::shared_ptr<const T> p1 = std::make_shared<const T>(t1);
|
||||||
|
assert(*p0 == t0);
|
||||||
|
assert(*p1 == t1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
int nc = globalMemCounter.outstanding_new;
|
int nc = globalMemCounter.outstanding_new;
|
||||||
|
@ -108,5 +128,9 @@ int main(int, char**)
|
||||||
#endif
|
#endif
|
||||||
assert(A::count == 0);
|
assert(A::count == 0);
|
||||||
|
|
||||||
|
test<bool>(true);
|
||||||
|
test<int>(3);
|
||||||
|
test<double>(5.0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
//
|
|
||||||
// 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>
|
|
||||||
|
|
||||||
// shared_ptr
|
|
||||||
|
|
||||||
// template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args);
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include "test_macros.h"
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void test(const T &t0)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
T t1 = t0;
|
|
||||||
std::shared_ptr<T> p0 = std::make_shared<T>(t0);
|
|
||||||
std::shared_ptr<T> p1 = std::make_shared<T>(t1);
|
|
||||||
assert(*p0 == t0);
|
|
||||||
assert(*p1 == t1);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const T t1 = t0;
|
|
||||||
std::shared_ptr<const T> p0 = std::make_shared<const T>(t0);
|
|
||||||
std::shared_ptr<const T> p1 = std::make_shared<const T>(t1);
|
|
||||||
assert(*p0 == t0);
|
|
||||||
assert(*p1 == t1);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
volatile T t1 = t0;
|
|
||||||
std::shared_ptr<volatile T> p0 = std::make_shared<volatile T>(t0);
|
|
||||||
std::shared_ptr<volatile T> p1 = std::make_shared<volatile T>(t1);
|
|
||||||
assert(*p0 == t0);
|
|
||||||
assert(*p1 == t1);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const volatile T t1 = t0;
|
|
||||||
std::shared_ptr<const volatile T> p0 = std::make_shared<const volatile T>(t0);
|
|
||||||
std::shared_ptr<const volatile T> p1 = std::make_shared<const volatile T>(t1);
|
|
||||||
assert(*p0 == t0);
|
|
||||||
assert(*p1 == t1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int, char**)
|
|
||||||
{
|
|
||||||
test<bool>(true);
|
|
||||||
test<int>(3);
|
|
||||||
test<double>(5.0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
Reference in New Issue