diff --git a/stl/inc/atomic b/stl/inc/atomic index b9b48316567..9f4da0a47e3 100644 --- a/stl/inc/atomic +++ b/stl/inc/atomic @@ -586,8 +586,7 @@ struct _Atomic_storage { _Atomic_storage() = default; - /* implicit */ constexpr _Atomic_storage(conditional_t, _Ty, const _TVal> _Value) noexcept - : _Storage(_Value) { + /* implicit */ constexpr _Atomic_storage(const _Ty& _Value) noexcept : _Storage(_Value) { // non-atomically initialize this atomic } @@ -714,13 +713,11 @@ public: template struct _Atomic_storage<_Ty, 1> { // lock-free using 1-byte intrinsics - using _TVal = remove_reference_t<_Ty>; _Atomic_storage() = default; - /* implicit */ constexpr _Atomic_storage(conditional_t, _Ty, const _TVal> _Value) noexcept - : _Storage{_Value} { + /* implicit */ constexpr _Atomic_storage(const _Ty& _Value) noexcept : _Storage{_Value} { // non-atomically initialize this atomic } @@ -817,13 +814,11 @@ struct _Atomic_storage<_Ty, 1> { // lock-free using 1-byte intrinsics template struct _Atomic_storage<_Ty, 2> { // lock-free using 2-byte intrinsics - using _TVal = remove_reference_t<_Ty>; _Atomic_storage() = default; - /* implicit */ constexpr _Atomic_storage(conditional_t, _Ty, const _TVal> _Value) noexcept - : _Storage{_Value} { + /* implicit */ constexpr _Atomic_storage(const _Ty& _Value) noexcept : _Storage{_Value} { // non-atomically initialize this atomic } @@ -919,13 +914,11 @@ struct _Atomic_storage<_Ty, 2> { // lock-free using 2-byte intrinsics template struct _Atomic_storage<_Ty, 4> { // lock-free using 4-byte intrinsics - using _TVal = remove_reference_t<_Ty>; _Atomic_storage() = default; - /* implicit */ constexpr _Atomic_storage(conditional_t, _Ty, const _TVal> _Value) noexcept - : _Storage{_Value} { + /* implicit */ constexpr _Atomic_storage(const _Ty& _Value) noexcept : _Storage{_Value} { // non-atomically initialize this atomic } @@ -1021,13 +1014,11 @@ struct _Atomic_storage<_Ty, 4> { // lock-free using 4-byte intrinsics template struct _Atomic_storage<_Ty, 8> { // lock-free using 8-byte intrinsics - using _TVal = remove_reference_t<_Ty>; _Atomic_storage() = default; - /* implicit */ constexpr _Atomic_storage(conditional_t, _Ty, const _TVal> _Value) noexcept - : _Storage{_Value} { + /* implicit */ constexpr _Atomic_storage(const _Ty& _Value) noexcept : _Storage{_Value} { // non-atomically initialize this atomic } @@ -1148,7 +1139,8 @@ struct _Atomic_storage<_Ty&, 16> { // lock-free using 16-byte intrinsics _Atomic_storage() = default; - /* implicit */ constexpr _Atomic_storage(conditional_t, _Ty&, const _TVal> _Value) noexcept + // TRANSITION, ABI: replace _this_ occurrence of '_Ty&' with 'const _Ty&' + /* implicit */ constexpr _Atomic_storage(_Ty& _Value) noexcept : _Storage{_Value} {} // non-atomically initialize this atomic void store(const _TVal _Value) noexcept { // store with sequential consistency @@ -2121,10 +2113,11 @@ public: using value_type = _Ty; - using _Base::_Base; - + template , int> = 0> constexpr atomic() noexcept(is_nothrow_default_constructible_v<_Ty>) : _Base() {} + /* implicit */ constexpr atomic(const _Ty _Value) noexcept : _Base(_Value) {} + atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; diff --git a/tests/std/tests/Dev11_0863628_atomic_compare_exchange/test.cpp b/tests/std/tests/Dev11_0863628_atomic_compare_exchange/test.cpp index 52958c67c01..5d74ec0cce8 100644 --- a/tests/std/tests/Dev11_0863628_atomic_compare_exchange/test.cpp +++ b/tests/std/tests/Dev11_0863628_atomic_compare_exchange/test.cpp @@ -12,11 +12,11 @@ #include #include #include +#include #include #include #include - using namespace std; #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) @@ -438,6 +438,17 @@ STATIC_ASSERT(atomic::is_always_lock_free); STATIC_ASSERT(atomic::is_always_lock_free); #endif // _HAS_CXX17 +// Also test LWG-4169 std::atomic's default constructor should be constrained +// (backported to C++14/17 modes as we backported P0883R2) +STATIC_ASSERT(is_default_constructible_v>); +STATIC_ASSERT(is_default_constructible_v>); +STATIC_ASSERT(is_default_constructible_v>); +STATIC_ASSERT(is_default_constructible_v>); +STATIC_ASSERT(is_default_constructible_v>); +STATIC_ASSERT(!is_default_constructible_v>>); +STATIC_ASSERT(!is_default_constructible_v>>); +STATIC_ASSERT(!is_default_constructible_v>>); + // Also test P0418R2 atomic compare_exchange memory_order Requirements void test_compare_exchange_relaxed_memory_orders() {