summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/atomics
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2017-07-10 04:16:50 +0000
committerEric Fiselier <eric@efcs.ca>2017-07-10 04:16:50 +0000
commitcc859306f499cc0438d3df3baf22fec5055bb38e (patch)
tree628810fa3f6242a52b51a6e9de825381d451dfee /libcxx/test/std/atomics
parent98cce00371d271c9da8de806e4cc4c886a85d56c (diff)
downloadbcm5719-llvm-cc859306f499cc0438d3df3baf22fec5055bb38e.tar.gz
bcm5719-llvm-cc859306f499cc0438d3df3baf22fec5055bb38e.zip
Work around PR31864 - ATOMIC_LLONG_LOCK_FREE is incorrect in 32 bit builds
llvm-svn: 307517
Diffstat (limited to 'libcxx/test/std/atomics')
-rw-r--r--libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp37
1 files changed, 35 insertions, 2 deletions
diff --git a/libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp b/libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp
index e42e9f28448..7a4090b9c25 100644
--- a/libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp
@@ -25,6 +25,40 @@ template <typename T> void checkAlwaysLockFree() {
assert(std::atomic<T>().is_lock_free());
}
+// FIXME: This separate test is needed to work around llvm.org/PR31864
+// which causes ATOMIC_LLONG_LOCK_FREE to be defined as '1' in 32-bit builds
+// even though __atomic_always_lock_free returns true for the same type.
+constexpr bool NeedWorkaroundForPR31864 =
+#if defined(__clang__)
+(sizeof(void*) == 4); // Needed on 32 bit builds
+#else
+false;
+#endif
+
+template <bool Disable = NeedWorkaroundForPR31864,
+ std::enable_if_t<!Disable>* = nullptr,
+ class LLong = long long,
+ class ULLong = unsigned long long>
+void checkLongLongTypes() {
+ static_assert(std::atomic<LLong>::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE));
+ static_assert(std::atomic<ULLong>::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE));
+}
+
+// Used to make the calls to __atomic_always_lock_free dependent on a template
+// parameter.
+template <class T> constexpr size_t getSizeOf() { return sizeof(T); }
+
+template <bool Enable = NeedWorkaroundForPR31864,
+ std::enable_if_t<Enable>* = nullptr,
+ class LLong = long long,
+ class ULLong = unsigned long long>
+void checkLongLongTypes() {
+ constexpr bool ExpectLockFree = __atomic_always_lock_free(getSizeOf<LLong>(), 0);
+ static_assert(std::atomic<LLong>::is_always_lock_free == ExpectLockFree, "");
+ static_assert(std::atomic<ULLong>::is_always_lock_free == ExpectLockFree, "");
+ static_assert((0 != ATOMIC_LLONG_LOCK_FREE) == ExpectLockFree, "");
+}
+
int main()
{
// structs and unions can't be defined in the template invocation.
@@ -94,8 +128,7 @@ int main()
static_assert(std::atomic<unsigned int>::is_always_lock_free == (2 == ATOMIC_INT_LOCK_FREE));
static_assert(std::atomic<long>::is_always_lock_free == (2 == ATOMIC_LONG_LOCK_FREE));
static_assert(std::atomic<unsigned long>::is_always_lock_free == (2 == ATOMIC_LONG_LOCK_FREE));
- static_assert(std::atomic<long long>::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE));
- static_assert(std::atomic<unsigned long long>::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE));
+ checkLongLongTypes();
static_assert(std::atomic<void*>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE));
static_assert(std::atomic<std::nullptr_t>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE));
}
OpenPOWER on IntegriCloud