@@ -25,6 +25,40 @@ template <typename T> void checkAlwaysLockFree() {
25
25
assert (std::atomic<T>().is_lock_free ());
26
26
}
27
27
28
+ // FIXME: This separate test is needed to work around llvm.org/PR31864
29
+ // which causes ATOMIC_LLONG_LOCK_FREE to be defined as '1' in 32-bit builds
30
+ // even though __atomic_always_lock_free returns true for the same type.
31
+ constexpr bool NeedWorkaroundForPR31864 =
32
+ #if defined(__clang__)
33
+ (sizeof (void *) == 4 ); // Needed on 32 bit builds
34
+ #else
35
+ false ;
36
+ #endif
37
+
38
+ template <bool Disable = NeedWorkaroundForPR31864,
39
+ std::enable_if_t <!Disable>* = nullptr ,
40
+ class LLong = long long ,
41
+ class ULLong = unsigned long long >
42
+ void checkLongLongTypes () {
43
+ static_assert (std::atomic<LLong>::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE));
44
+ static_assert (std::atomic<ULLong>::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE));
45
+ }
46
+
47
+ // Used to make the calls to __atomic_always_lock_free dependent on a template
48
+ // parameter.
49
+ template <class T > constexpr size_t getSizeOf () { return sizeof (T); }
50
+
51
+ template <bool Enable = NeedWorkaroundForPR31864,
52
+ std::enable_if_t <Enable>* = nullptr ,
53
+ class LLong = long long ,
54
+ class ULLong = unsigned long long >
55
+ void checkLongLongTypes () {
56
+ constexpr bool ExpectLockFree = __atomic_always_lock_free (getSizeOf<LLong>(), 0 );
57
+ static_assert (std::atomic<LLong>::is_always_lock_free == ExpectLockFree, " " );
58
+ static_assert (std::atomic<ULLong>::is_always_lock_free == ExpectLockFree, " " );
59
+ static_assert ((0 != ATOMIC_LLONG_LOCK_FREE) == ExpectLockFree, " " );
60
+ }
61
+
28
62
int main ()
29
63
{
30
64
// structs and unions can't be defined in the template invocation.
@@ -94,8 +128,7 @@ int main()
94
128
static_assert (std::atomic<unsigned int >::is_always_lock_free == (2 == ATOMIC_INT_LOCK_FREE));
95
129
static_assert (std::atomic<long >::is_always_lock_free == (2 == ATOMIC_LONG_LOCK_FREE));
96
130
static_assert (std::atomic<unsigned long >::is_always_lock_free == (2 == ATOMIC_LONG_LOCK_FREE));
97
- static_assert (std::atomic<long long >::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE));
98
- static_assert (std::atomic<unsigned long long >::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE));
131
+ checkLongLongTypes ();
99
132
static_assert (std::atomic<void *>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE));
100
133
static_assert (std::atomic<std::nullptr_t >::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE));
101
134
}
0 commit comments