Skip to content
Merged
9 changes: 8 additions & 1 deletion libcxx/include/__atomic/atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <__type_traits/is_integral.h>
#include <__type_traits/is_nothrow_constructible.h>
#include <__type_traits/is_same.h>
#include <__type_traits/is_trivially_copyable.h>
#include <__type_traits/remove_const.h>
#include <__type_traits/remove_pointer.h>
#include <__type_traits/remove_volatile.h>
Expand Down Expand Up @@ -230,8 +231,14 @@ struct __atomic_waitable_traits<__atomic_base<_Tp, _IsIntegral> > {
}
};

template <typename _Tp>
struct __check_atomic_mandates {
using type _LIBCPP_NODEBUG = _Tp;
static_assert(is_trivially_copyable<_Tp>::value, "std::atomic<T> requires that 'T' be a trivially copyable type");
};

template <class _Tp>
struct atomic : public __atomic_base<_Tp> {
struct atomic : public __atomic_base<typename __check_atomic_mandates<_Tp>::type> {
using __base _LIBCPP_NODEBUG = __atomic_base<_Tp>;

#if _LIBCPP_STD_VER >= 20
Expand Down
3 changes: 0 additions & 3 deletions libcxx/include/__atomic/support.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#define _LIBCPP___ATOMIC_SUPPORT_H

#include <__config>
#include <__type_traits/is_trivially_copyable.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
Expand Down Expand Up @@ -113,8 +112,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD

template <typename _Tp, typename _Base = __cxx_atomic_base_impl<_Tp> >
struct __cxx_atomic_impl : public _Base {
static_assert(is_trivially_copyable<_Tp>::value, "std::atomic<T> requires that 'T' be a trivially copyable type");

_LIBCPP_HIDE_FROM_ABI __cxx_atomic_impl() _NOEXCEPT = default;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT : _Base(__value) {}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,23 @@
//
//===----------------------------------------------------------------------===//

// XFAIL: FROZEN-CXX03-HEADERS-FIXME

// <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_) { }
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@*:* {{std::atomic<T> requires that 'T' be a trivially copyable type}}
std::atomic<NotTriviallyCopyable> a(
x); // expected-error@*:* {{std::atomic<T> requires that 'T' be a trivially copyable type}}
}