diff options
author | Joe Loser <joeloser93@gmail.com> | 2021-09-22 11:46:21 -0400 |
---|---|---|
committer | Joe Loser <joeloser93@gmail.com> | 2021-09-22 11:47:38 -0400 |
commit | 400b33e18d27d801ec5ad1cc52b34c6d8bed64aa (patch) | |
tree | e9407e1e083aa6ea64651f03760268146b7098c9 /libcxx | |
parent | ca999f719117f916b333a794cc8c59984ae40dd2 (diff) | |
download | llvm-400b33e18d27d801ec5ad1cc52b34c6d8bed64aa.tar.gz |
[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
Diffstat (limited to 'libcxx')
6 files changed, 42 insertions, 69 deletions
diff --git a/libcxx/TODO.TXT b/libcxx/TODO.TXT index 4742b5b0ddc2..bc785546b48e 100644 --- a/libcxx/TODO.TXT +++ b/libcxx/TODO.TXT @@ -21,4 +21,3 @@ Misc Tasks * Find all sequences of >2 underscores and eradicate them. * run clang-tidy on libc++ * Document the "conditionally-supported" bits of libc++ -* Put a static_assert in std::allocator to deny const/volatile types (LWG 2447) diff --git a/libcxx/include/__memory/allocator.h b/libcxx/include/__memory/allocator.h index 84dc7d333efb..f99bee2b8f1b 100644 --- a/libcxx/include/__memory/allocator.h +++ b/libcxx/include/__memory/allocator.h @@ -80,6 +80,7 @@ template <class _Tp> class _LIBCPP_TEMPLATE_VIS allocator : private __non_trivial_if<!is_void<_Tp>::value, allocator<_Tp> > { + static_assert(!is_volatile<_Tp>::value, "std::allocator does not support volatile types"); public: typedef size_t size_type; typedef ptrdiff_t difference_type; @@ -162,6 +163,7 @@ template <class _Tp> class _LIBCPP_TEMPLATE_VIS 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: typedef size_t size_type; typedef ptrdiff_t difference_type; diff --git a/libcxx/test/libcxx/memory/allocator_volatile.verify.cpp b/libcxx/test/libcxx/memory/allocator_volatile.verify.cpp new file mode 100644 index 000000000000..b3ee09def3a3 --- /dev/null +++ b/libcxx/test/libcxx/memory/allocator_volatile.verify.cpp @@ -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}} diff --git a/libcxx/test/std/concepts/concepts.lang/concept.default.init/default_initializable.compile.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concept.default.init/default_initializable.compile.pass.cpp index 3519c57f3b97..930282f55a5d 100644 --- a/libcxx/test/std/concepts/concepts.lang/concept.default.init/default_initializable.compile.pass.cpp +++ b/libcxx/test/std/concepts/concepts.lang/concept.default.init/default_initializable.compile.pass.cpp @@ -204,8 +204,6 @@ void test() test_true <std::deque< int>>(); #ifdef _LIBCPP_VERSION test_true <std::deque<const int>>(); - test_true <std::deque< volatile int>>(); - test_true <std::deque<const volatile int>>(); #endif // _LIBCPP_VERSION test_true <std::forward_list<int>>(); test_true <std::list<int>>(); @@ -227,8 +225,6 @@ void test() test_true <std::stack< int>>(); #ifdef _LIBCPP_VERSION test_true <std::stack<const int>>(); - test_true <std::stack< volatile int>>(); - test_true <std::stack<const volatile int>>(); #endif // _LIBCPP_VERSION test_true <std::queue<int>>(); test_true <std::priority_queue<int>>(); diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp index 25355cb2430a..e29ae08ce423 100644 --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.pass.cpp @@ -73,6 +73,26 @@ void test_pointer_to_function() { void test_pointer_to_function() {} #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 nc = globalMemCounter.outstanding_new; @@ -108,5 +128,9 @@ int main(int, char**) #endif assert(A::count == 0); + test<bool>(true); + test<int>(3); + test<double>(5.0); + return 0; } diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.volatile.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.volatile.pass.cpp deleted file mode 100644 index eb7f75aed511..000000000000 --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.volatile.pass.cpp +++ /dev/null @@ -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; -} |