[libc++] Refactor tests for trivially copyable atomics
- Replace irrelevant synopsis by a comment - Use a .verify.cpp test instead of .compile.fail.cpp - Remove unnecessary includes in one of the tests (was a copy-paste error) Differential Revision: https://reviews.llvm.org/D114094
This commit is contained in:
parent
bf834b2629
commit
3e957e5d66
|
@ -1440,7 +1440,7 @@ template <typename _Tp,
|
||||||
#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
|
#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
|
||||||
struct __cxx_atomic_impl : public _Base {
|
struct __cxx_atomic_impl : public _Base {
|
||||||
static_assert(is_trivially_copyable<_Tp>::value,
|
static_assert(is_trivially_copyable<_Tp>::value,
|
||||||
"std::atomic<Tp> requires that 'Tp' be a trivially copyable type");
|
"std::atomic<T> requires that 'T' be a trivially copyable type");
|
||||||
|
|
||||||
_LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT _LIBCPP_DEFAULT
|
_LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT _LIBCPP_DEFAULT
|
||||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
|
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
|
||||||
|
|
|
@ -1,71 +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
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
// <atomic>
|
|
||||||
|
|
||||||
// template <class T>
|
|
||||||
// struct atomic
|
|
||||||
// {
|
|
||||||
// bool is_lock_free() const volatile noexcept;
|
|
||||||
// bool is_lock_free() const noexcept;
|
|
||||||
// void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
|
|
||||||
// void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
|
|
||||||
// T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
|
|
||||||
// T load(memory_order m = memory_order_seq_cst) const noexcept;
|
|
||||||
// operator T() const volatile noexcept;
|
|
||||||
// operator T() const noexcept;
|
|
||||||
// T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
|
|
||||||
// T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
|
|
||||||
// bool compare_exchange_weak(T& expc, T desr,
|
|
||||||
// memory_order s, memory_order f) volatile noexcept;
|
|
||||||
// bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
|
|
||||||
// bool compare_exchange_strong(T& expc, T desr,
|
|
||||||
// memory_order s, memory_order f) volatile noexcept;
|
|
||||||
// bool compare_exchange_strong(T& expc, T desr,
|
|
||||||
// memory_order s, memory_order f) noexcept;
|
|
||||||
// bool compare_exchange_weak(T& expc, T desr,
|
|
||||||
// memory_order m = memory_order_seq_cst) volatile noexcept;
|
|
||||||
// bool compare_exchange_weak(T& expc, T desr,
|
|
||||||
// memory_order m = memory_order_seq_cst) noexcept;
|
|
||||||
// bool compare_exchange_strong(T& expc, T desr,
|
|
||||||
// memory_order m = memory_order_seq_cst) volatile noexcept;
|
|
||||||
// bool compare_exchange_strong(T& expc, T desr,
|
|
||||||
// memory_order m = memory_order_seq_cst) noexcept;
|
|
||||||
//
|
|
||||||
// atomic() noexcept = default;
|
|
||||||
// constexpr atomic(T desr) noexcept;
|
|
||||||
// atomic(const atomic&) = delete;
|
|
||||||
// atomic& operator=(const atomic&) = delete;
|
|
||||||
// atomic& operator=(const atomic&) volatile = delete;
|
|
||||||
// T operator=(T) volatile noexcept;
|
|
||||||
// T operator=(T) noexcept;
|
|
||||||
// };
|
|
||||||
|
|
||||||
#include <atomic>
|
|
||||||
#include <new>
|
|
||||||
#include <cassert>
|
|
||||||
#include <thread> // for thread_id
|
|
||||||
#include <chrono> // for nanoseconds
|
|
||||||
|
|
||||||
struct NotTriviallyCopyable {
|
|
||||||
NotTriviallyCopyable ( int i ) : i_(i) {}
|
|
||||||
NotTriviallyCopyable ( const NotTriviallyCopyable &rhs) : i_(rhs.i_) {}
|
|
||||||
int i_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class >
|
|
||||||
void test ( T t ) {
|
|
||||||
std::atomic<T> t0(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int, char**)
|
|
||||||
{
|
|
||||||
test(NotTriviallyCopyable(42));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -11,42 +11,9 @@
|
||||||
// <atomic>
|
// <atomic>
|
||||||
|
|
||||||
// template <class T>
|
// template <class T>
|
||||||
// struct atomic
|
// struct atomic;
|
||||||
// {
|
|
||||||
// bool is_lock_free() const volatile noexcept;
|
// Make sure atomic<TriviallyCopyable> can be instantiated.
|
||||||
// bool is_lock_free() const noexcept;
|
|
||||||
// void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
|
|
||||||
// void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
|
|
||||||
// T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
|
|
||||||
// T load(memory_order m = memory_order_seq_cst) const noexcept;
|
|
||||||
// operator T() const volatile noexcept;
|
|
||||||
// operator T() const noexcept;
|
|
||||||
// T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
|
|
||||||
// T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
|
|
||||||
// bool compare_exchange_weak(T& expc, T desr,
|
|
||||||
// memory_order s, memory_order f) volatile noexcept;
|
|
||||||
// bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
|
|
||||||
// bool compare_exchange_strong(T& expc, T desr,
|
|
||||||
// memory_order s, memory_order f) volatile noexcept;
|
|
||||||
// bool compare_exchange_strong(T& expc, T desr,
|
|
||||||
// memory_order s, memory_order f) noexcept;
|
|
||||||
// bool compare_exchange_weak(T& expc, T desr,
|
|
||||||
// memory_order m = memory_order_seq_cst) volatile noexcept;
|
|
||||||
// bool compare_exchange_weak(T& expc, T desr,
|
|
||||||
// memory_order m = memory_order_seq_cst) noexcept;
|
|
||||||
// bool compare_exchange_strong(T& expc, T desr,
|
|
||||||
// memory_order m = memory_order_seq_cst) volatile noexcept;
|
|
||||||
// bool compare_exchange_strong(T& expc, T desr,
|
|
||||||
// memory_order m = memory_order_seq_cst) noexcept;
|
|
||||||
//
|
|
||||||
// atomic() noexcept = default;
|
|
||||||
// constexpr atomic(T desr) noexcept;
|
|
||||||
// atomic(const atomic&) = delete;
|
|
||||||
// atomic& operator=(const atomic&) = delete;
|
|
||||||
// atomic& operator=(const atomic&) volatile = delete;
|
|
||||||
// T operator=(T) volatile noexcept;
|
|
||||||
// T operator=(T) noexcept;
|
|
||||||
// };
|
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
@ -54,23 +21,20 @@
|
||||||
#include <thread> // for thread_id
|
#include <thread> // for thread_id
|
||||||
#include <chrono> // for nanoseconds
|
#include <chrono> // for nanoseconds
|
||||||
|
|
||||||
#include "test_macros.h"
|
|
||||||
|
|
||||||
struct TriviallyCopyable {
|
struct TriviallyCopyable {
|
||||||
TriviallyCopyable ( int i ) : i_(i) {}
|
explicit TriviallyCopyable(int i) : i_(i) { }
|
||||||
int i_;
|
int i_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void test ( T t ) {
|
void test(T t) {
|
||||||
std::atomic<T> t0(t);
|
std::atomic<T> t0(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int, char**)
|
int main(int, char**) {
|
||||||
{
|
test(TriviallyCopyable(42));
|
||||||
test(TriviallyCopyable(42));
|
test(std::this_thread::get_id());
|
||||||
test(std::this_thread::get_id());
|
test(std::chrono::nanoseconds(2));
|
||||||
test(std::chrono::nanoseconds(2));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// UNSUPPORTED: libcpp-has-no-threads
|
||||||
|
|
||||||
|
// <atomic>
|
||||||
|
|
||||||
|
// template <class T>
|
||||||
|
// struct atomic;
|
||||||
|
|
||||||
|
// This test checks that we static_assert inside std::atomic<T> when T
|
||||||
|
// is not trivially copyable, however Clang will sometimes emit additional
|
||||||
|
// errors while trying to instantiate the rest of std::atomic<T>.
|
||||||
|
// We silence those to make the test more robust.
|
||||||
|
// ADDITIONAL_COMPILE_FLAGS: -Xclang -verify-ignore-unexpected=error
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
struct NotTriviallyCopyable {
|
||||||
|
explicit NotTriviallyCopyable(int i) : i_(i) { }
|
||||||
|
NotTriviallyCopyable(const NotTriviallyCopyable &rhs) : i_(rhs.i_) { }
|
||||||
|
int i_;
|
||||||
|
};
|
||||||
|
|
||||||
|
void f() {
|
||||||
|
NotTriviallyCopyable x(42);
|
||||||
|
std::atomic<NotTriviallyCopyable> a(x); // expected-error@atomic:* {{std::atomic<T> requires that 'T' be a trivially copyable type}}
|
||||||
|
}
|
Loading…
Reference in New Issue