diff --git a/libcxx/include/__atomic/atomic.h b/libcxx/include/__atomic/atomic.h index 975a479e20400..278d7f2854bae 100644 --- a/libcxx/include/__atomic/atomic.h +++ b/libcxx/include/__atomic/atomic.h @@ -40,6 +40,8 @@ struct __atomic_base // false { mutable __cxx_atomic_impl<_Tp> __a_; + using value_type = _Tp; + #if _LIBCPP_STD_VER >= 17 static constexpr bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value; #endif @@ -145,6 +147,8 @@ template struct __atomic_base<_Tp, true> : public __atomic_base<_Tp, false> { using __base _LIBCPP_NODEBUG = __atomic_base<_Tp, false>; + using difference_type = typename __base::value_type; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __atomic_base() _NOEXCEPT = default; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {} @@ -229,8 +233,6 @@ struct __atomic_waitable_traits<__atomic_base<_Tp, _IsIntegral> > { template struct atomic : public __atomic_base<_Tp> { using __base _LIBCPP_NODEBUG = __atomic_base<_Tp>; - using value_type = _Tp; - using difference_type = value_type; #if _LIBCPP_STD_VER >= 20 _LIBCPP_HIDE_FROM_ABI atomic() = default; @@ -258,8 +260,8 @@ struct atomic : public __atomic_base<_Tp> { template struct atomic<_Tp*> : public __atomic_base<_Tp*> { using __base _LIBCPP_NODEBUG = __atomic_base<_Tp*>; - using value_type = _Tp*; - using difference_type = ptrdiff_t; + + using difference_type = ptrdiff_t; _LIBCPP_HIDE_FROM_ABI atomic() _NOEXCEPT = default; diff --git a/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.cpp b/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.cpp index fbe7dbbd6d9f0..320ef57dcb6f9 100644 --- a/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.cpp +++ b/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.verify.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + // // template @@ -63,12 +65,12 @@ struct S { void member_function_pointer() { { volatile std::atomic fun; - // expected-error@*:* {{no member named 'fetch_add' in}} + // expected-error@*:* {{no matching function for call to 'atomic_fetch_add'}} std::atomic_fetch_add(&fun, 0); } { std::atomic fun; - // expected-error@*:* {{no member named 'fetch_add' in}} + // expected-error@*:* {{no matching function for call to 'atomic_fetch_add'}} std::atomic_fetch_add(&fun, 0); } } diff --git a/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.cpp b/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.cpp index 176a38c7c0f7f..bdd8089feb281 100644 --- a/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.cpp +++ b/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.verify.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + // // template @@ -66,12 +68,12 @@ struct S { void member_function_pointer() { { volatile std::atomic fun; - // expected-error@*:* {{no member named 'fetch_add' in}} + // expected-error@*:* {{no matching function for call to 'atomic_fetch_add_explicit'}} std::atomic_fetch_add_explicit(&fun, 0, std::memory_order_relaxed); } { std::atomic fun; - // expected-error@*:* {{no member named 'fetch_add' in}} + // expected-error@*:* {{no matching function for call to 'atomic_fetch_add_explicit'}} std::atomic_fetch_add_explicit(&fun, 0, std::memory_order_relaxed); } } diff --git a/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.cpp b/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.cpp index 6f3039dab6697..2c9f89891d5be 100644 --- a/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.cpp +++ b/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.verify.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + // // template @@ -63,12 +65,12 @@ struct S { void member_function_pointer() { { volatile std::atomic fun; - // expected-error@*:* {{no member named 'fetch_sub' in}} + // expected-error@*:* {{no matching function for call to 'atomic_fetch_sub'}} std::atomic_fetch_sub(&fun, 0); } { std::atomic fun; - // expected-error@*:* {{no member named 'fetch_sub' in}} + // expected-error@*:* {{no matching function for call to 'atomic_fetch_sub'}} std::atomic_fetch_sub(&fun, 0); } } diff --git a/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.cpp b/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.cpp index 1b3c58fa87551..88c42750b608a 100644 --- a/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.cpp +++ b/libcxx/test/libcxx/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.verify.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + // // template @@ -66,12 +68,12 @@ struct S { void member_function_pointer() { { volatile std::atomic fun; - // expected-error@*:* {{no member named 'fetch_sub' in}} + // expected-error@*:* {{no matching function for call to 'atomic_fetch_sub_explicit'}} std::atomic_fetch_sub_explicit(&fun, 0, std::memory_order_relaxed); } { std::atomic fun; - // expected-error@*:* {{no member named 'fetch_sub' in}} + // expected-error@*:* {{no matching function for call to 'atomic_fetch_sub_explicit'}} std::atomic_fetch_sub_explicit(&fun, 0, std::memory_order_relaxed); } } diff --git a/libcxx/test/std/atomics/types.pass.cpp b/libcxx/test/std/atomics/types.pass.cpp index 33512c037804f..8737694e2a070 100644 --- a/libcxx/test/std/atomics/types.pass.cpp +++ b/libcxx/test/std/atomics/types.pass.cpp @@ -17,6 +17,9 @@ // typedef T value_type; // }; +// atomic still has a difference_type in the C++03 frozen headers +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + #include #include #include @@ -29,163 +32,185 @@ # include #endif -template -struct test_atomic -{ - test_atomic() - { - A a; (void)a; -#if TEST_STD_VER >= 17 - static_assert((std::is_same_v), ""); -#endif - } +// detect existence of the difference_type member type +template +using myvoid_t = void; +template +struct has_difference_type : std::false_type {}; +template +struct has_difference_type > : std::true_type {}; + +template ::value && !std::is_same::value), + bool Floating = std::is_floating_point::value, + bool Pointer = std::is_pointer::value> +struct test_atomic { + test_atomic() { + static_assert(!Integral && !Floating && !Pointer, ""); + using A = std::atomic; + A a; + (void)a; + static_assert(std::is_same::value, ""); + static_assert(!has_difference_type::value, ""); + } }; -template -struct test_atomic -{ - test_atomic() - { - A a; (void)a; -#if TEST_STD_VER >= 17 - static_assert((std::is_same_v), ""); - static_assert((std::is_same_v), ""); -#endif - } +template +struct test_atomic { + test_atomic() { + static_assert(!std::is_same::value, ""); + using A = std::atomic; + A a; + (void)a; + static_assert(std::is_same::value, ""); + static_assert(std::is_same::value, ""); + } }; -template -struct test_atomic -{ - test_atomic() - { - A a; (void)a; -#if TEST_STD_VER >= 17 - static_assert((std::is_same_v), ""); - static_assert((std::is_same_v), ""); +template +struct test_atomic { + test_atomic() { + using A = std::atomic; + A a; + (void)a; + static_assert(std::is_same::value, ""); +#if TEST_STD_VER >= 20 + static_assert(std::is_same::value, ""); +#else + static_assert(!has_difference_type::value, ""); #endif - } + } }; template -void -test() -{ +struct test_atomic { + test_atomic() { using A = std::atomic; -#if TEST_STD_VER >= 17 - static_assert((std::is_same_v), ""); -#endif - test_atomic::value && !std::is_same::value>(); + A a; + (void)a; + static_assert(std::is_same::value, ""); + static_assert(std::is_same::value, ""); + } +}; + +template +void test() { + using A = std::atomic; + static_assert(std::is_same::value, ""); + test_atomic(); } struct TriviallyCopyable { - int i_; + int i_; }; -struct WeirdTriviallyCopyable -{ - char i, j, k; /* the 3 chars of doom */ +struct WeirdTriviallyCopyable { + char i, j, k; /* the 3 chars of doom */ }; -struct PaddedTriviallyCopyable -{ - char i; int j; /* probably lock-free? */ +struct PaddedTriviallyCopyable { + char i; + int j; /* probably lock-free? */ }; -struct LargeTriviallyCopyable -{ - int i, j[127]; /* decidedly not lock-free */ +struct LargeTriviallyCopyable { + int i, j[127]; /* decidedly not lock-free */ }; -int main(int, char**) -{ - test (); - test (); - test (); - test (); - test (); - test (); - test (); - test (); - test (); - test (); - test (); - test (); +int main(int, char**) { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); #if TEST_STD_VER > 17 && defined(__cpp_char8_t) - test (); + test(); #endif - test (); - test (); + test(); + test(); #ifndef TEST_HAS_NO_WIDE_CHARACTERS - test (); + test(); #endif - test (); - test (); - test (); - test (); - test (); - test (); - test (); - test (); - - test (); - test (); - test (); - test (); - test (); - test (); - test (); - test (); - - test< std::int8_t> (); - test (); - test< std::int16_t> (); - test (); - test< std::int32_t> (); - test (); - test< std::int64_t> (); - test (); - - test (); - test (); - test (); - test (); - test (); - test (); - - test (); - test (); - - test(); - test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + + test< std::int8_t>(); + test(); + test< std::int16_t>(); + test(); + test< std::int32_t>(); + test(); + test< std::int64_t>(); + test(); + + test(); + test(); + test(); + test(); + test(); + test(); + + test(); + test(); + + test(); + test(); + test(); + test(); + test(); + + test(); + test(); #ifndef __APPLE__ // Apple doesn't ship libatomic - /* + /* These aren't going to be lock-free, so some libatomic.a is necessary. */ - test(); - test(); + test(); + test(); #endif #ifndef TEST_HAS_NO_THREADS - test(); + test(); #endif - test(); - test(); + test(); + test(); #if TEST_STD_VER >= 20 - test(); - static_assert(std::is_signed_v); - static_assert(std::is_integral_v); + test(); + static_assert(std::is_signed_v); + static_assert(std::is_integral_v); - test(); - static_assert(std::is_unsigned_v); - static_assert(std::is_integral_v); + test(); + static_assert(std::is_unsigned_v); + static_assert(std::is_integral_v); /* test>(); */ #endif - return 0; + return 0; }