diff --git a/libcxx/include/__atomic/atomic_base.h b/libcxx/include/__atomic/atomic_base.h index 87100ba5d8a50d..775d06d7570183 100644 --- a/libcxx/include/__atomic/atomic_base.h +++ b/libcxx/include/__atomic/atomic_base.h @@ -39,7 +39,7 @@ struct __atomic_base // false _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const volatile _NOEXCEPT - {return __cxx_atomic_is_lock_free(sizeof(_Tp));} + {return __cxx_atomic_is_lock_free(sizeof(__cxx_atomic_impl<_Tp>));} _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const _NOEXCEPT {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();} diff --git a/libcxx/test/libcxx/atomics/atomics.align/align.pass.cpp b/libcxx/test/libcxx/atomics/atomics.align/align.pass.cpp index 495d02fbe5c8d4..f9e01bd5d032bd 100644 --- a/libcxx/test/libcxx/atomics/atomics.align/align.pass.cpp +++ b/libcxx/test/libcxx/atomics/atomics.align/align.pass.cpp @@ -100,6 +100,7 @@ int main(int, char**) { CHECK_ALIGNMENT(struct Empty {}); CHECK_ALIGNMENT(struct OneInt { int i; }); CHECK_ALIGNMENT(struct IntArr2 { int i[2]; }); + CHECK_ALIGNMENT(struct FloatArr3 { float i[3]; }); CHECK_ALIGNMENT(struct LLIArr2 { long long int i[2]; }); CHECK_ALIGNMENT(struct LLIArr4 { long long int i[4]; }); CHECK_ALIGNMENT(struct LLIArr8 { long long int i[8]; }); diff --git a/libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp b/libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp index b2d83f0a6fe881..6d6e6477bc2511 100644 --- a/libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp +++ b/libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp @@ -21,7 +21,6 @@ template void checkAlwaysLockFree() { if (std::atomic::is_always_lock_free) { - LIBCPP_ASSERT(sizeof(std::atomic) == sizeof(T)); // technically not required, but libc++ does it that way assert(std::atomic().is_lock_free()); } } @@ -79,6 +78,7 @@ void run() CHECK_ALWAYS_LOCK_FREE(struct Empty {}); CHECK_ALWAYS_LOCK_FREE(struct OneInt { int i; }); CHECK_ALWAYS_LOCK_FREE(struct IntArr2 { int i[2]; }); + CHECK_ALWAYS_LOCK_FREE(struct FloatArr3 { float i[3]; }); CHECK_ALWAYS_LOCK_FREE(struct LLIArr2 { long long int i[2]; }); CHECK_ALWAYS_LOCK_FREE(struct LLIArr4 { long long int i[4]; }); CHECK_ALWAYS_LOCK_FREE(struct LLIArr8 { long long int i[8]; }); diff --git a/libcxx/test/std/atomics/atomics.types.generic/address.pass.cpp b/libcxx/test/std/atomics/atomics.types.generic/address.pass.cpp index b3aa1fc47629a3..0926628a2e9a89 100644 --- a/libcxx/test/std/atomics/atomics.types.generic/address.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.generic/address.pass.cpp @@ -80,8 +80,14 @@ do_test() typedef typename std::remove_pointer::type X; A obj(T(0)); assert(obj == T(0)); - bool b0 = obj.is_lock_free(); - ((void)b0); // mark as unused + { + bool lockfree = obj.is_lock_free(); + (void)lockfree; +#if TEST_STD_VER >= 17 + if (A::is_always_lock_free) + assert(lockfree); +#endif + } obj.store(T(0)); assert(obj == T(0)); obj.store(T(1), std::memory_order_release); diff --git a/libcxx/test/std/atomics/atomics.types.generic/bool.pass.cpp b/libcxx/test/std/atomics/atomics.types.generic/bool.pass.cpp index 78234ae6d96305..2609e5b56e798d 100644 --- a/libcxx/test/std/atomics/atomics.types.generic/bool.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.generic/bool.pass.cpp @@ -61,8 +61,14 @@ int main(int, char**) { volatile std::atomic obj(true); assert(obj == true); - bool b0 = obj.is_lock_free(); - (void)b0; // to placate scan-build + { + bool lockfree = obj.is_lock_free(); + (void)lockfree; +#if TEST_STD_VER >= 17 + if (std::atomic::is_always_lock_free) + assert(lockfree); +#endif + } obj.store(false); assert(obj == false); obj.store(true, std::memory_order_release); @@ -112,8 +118,14 @@ int main(int, char**) { std::atomic obj(true); assert(obj == true); - bool b0 = obj.is_lock_free(); - (void)b0; // to placate scan-build + { + bool lockfree = obj.is_lock_free(); + (void)lockfree; +#if TEST_STD_VER >= 17 + if (std::atomic::is_always_lock_free) + assert(lockfree); +#endif + } obj.store(false); assert(obj == false); obj.store(true, std::memory_order_release); @@ -163,8 +175,14 @@ int main(int, char**) { std::atomic_bool obj(true); assert(obj == true); - bool b0 = obj.is_lock_free(); - (void)b0; // to placate scan-build + { + bool lockfree = obj.is_lock_free(); + (void)lockfree; +#if TEST_STD_VER >= 17 + if (std::atomic_bool::is_always_lock_free) + assert(lockfree); +#endif + } obj.store(false); assert(obj == false); obj.store(true, std::memory_order_release); diff --git a/libcxx/test/std/atomics/atomics.types.generic/integral.pass.cpp b/libcxx/test/std/atomics/atomics.types.generic/integral.pass.cpp index 058db2dc3ab049..2695ff94da3065 100644 --- a/libcxx/test/std/atomics/atomics.types.generic/integral.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.generic/integral.pass.cpp @@ -98,8 +98,14 @@ do_test() { A obj(T(0)); assert(obj == T(0)); - bool b0 = obj.is_lock_free(); - ((void)b0); // mark as unused + { + bool lockfree = obj.is_lock_free(); + (void)lockfree; +#if TEST_STD_VER >= 17 + if (A::is_always_lock_free) + assert(lockfree); +#endif + } obj.store(T(0)); assert(obj == T(0)); obj.store(T(1), std::memory_order_release); diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp index 8b838f62abb1d3..39fa837f4807bf 100644 --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp @@ -27,8 +27,12 @@ struct TestFn { void operator()() const { typedef std::atomic A; T t = T(); + A a(t); bool b1 = std::atomic_is_lock_free(static_cast(&a)); + if (A::is_always_lock_free) + assert(b1); + volatile A va(t); bool b2 = std::atomic_is_lock_free(static_cast(&va)); assert(b1 == b2);