Skip to content

Commit cc85930

Browse files
committed
Work around PR31864 - ATOMIC_LLONG_LOCK_FREE is incorrect in 32 bit builds
llvm-svn: 307517
1 parent 98cce00 commit cc85930

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,40 @@ template <typename T> void checkAlwaysLockFree() {
2525
assert(std::atomic<T>().is_lock_free());
2626
}
2727

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+
2862
int main()
2963
{
3064
// structs and unions can't be defined in the template invocation.
@@ -94,8 +128,7 @@ int main()
94128
static_assert(std::atomic<unsigned int>::is_always_lock_free == (2 == ATOMIC_INT_LOCK_FREE));
95129
static_assert(std::atomic<long>::is_always_lock_free == (2 == ATOMIC_LONG_LOCK_FREE));
96130
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();
99132
static_assert(std::atomic<void*>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE));
100133
static_assert(std::atomic<std::nullptr_t>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE));
101134
}

0 commit comments

Comments
 (0)