1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: libcpp-has-no-threads
11 // ... test case crashes clang.
18 // bool is_lock_free() const volatile;
19 // bool is_lock_free() const;
20 // void store(T* desr, memory_order m = memory_order_seq_cst) volatile;
21 // void store(T* desr, memory_order m = memory_order_seq_cst);
22 // T* load(memory_order m = memory_order_seq_cst) const volatile;
23 // T* load(memory_order m = memory_order_seq_cst) const;
24 // operator T*() const volatile;
25 // operator T*() const;
26 // T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile;
27 // T* exchange(T* desr, memory_order m = memory_order_seq_cst);
28 // bool compare_exchange_weak(T*& expc, T* desr,
29 // memory_order s, memory_order f) volatile;
30 // bool compare_exchange_weak(T*& expc, T* desr,
31 // memory_order s, memory_order f);
32 // bool compare_exchange_strong(T*& expc, T* desr,
33 // memory_order s, memory_order f) volatile;
34 // bool compare_exchange_strong(T*& expc, T* desr,
35 // memory_order s, memory_order f);
36 // bool compare_exchange_weak(T*& expc, T* desr,
37 // memory_order m = memory_order_seq_cst) volatile;
38 // bool compare_exchange_weak(T*& expc, T* desr,
39 // memory_order m = memory_order_seq_cst);
40 // bool compare_exchange_strong(T*& expc, T* desr,
41 // memory_order m = memory_order_seq_cst) volatile;
42 // bool compare_exchange_strong(T*& expc, T* desr,
43 // memory_order m = memory_order_seq_cst);
44 // T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile;
45 // T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst);
46 // T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile;
47 // T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst);
49 // atomic() = default;
50 // constexpr atomic(T* desr);
51 // atomic(const atomic&) = delete;
52 // atomic& operator=(const atomic&) = delete;
53 // atomic& operator=(const atomic&) volatile = delete;
55 // T* operator=(T*) volatile;
57 // T* operator++(int) volatile;
58 // T* operator++(int);
59 // T* operator--(int) volatile;
60 // T* operator--(int);
61 // T* operator++() volatile;
63 // T* operator--() volatile;
65 // T* operator+=(ptrdiff_t op) volatile;
66 // T* operator+=(ptrdiff_t op);
67 // T* operator-=(ptrdiff_t op) volatile;
68 // T* operator-=(ptrdiff_t op);
73 #include <type_traits>
76 #include <cmpxchg_loop.h>
78 #include "test_macros.h"
80 template <class A, class T>
84 typedef typename std::remove_pointer<T>::type X;
86 bool b0 = obj.is_lock_free();
87 ((void)b0); // mark as unused
89 std::atomic_init(&obj, T(1));
91 std::atomic_init(&obj, T(2));
95 obj.store(T(1), std::memory_order_release);
97 assert(obj.load() == T(1));
98 assert(obj.load(std::memory_order_acquire) == T(1));
99 assert(obj.exchange(T(2)) == T(1));
101 assert(obj.exchange(T(3), std::memory_order_relaxed) == T(2));
104 assert(cmpxchg_weak_loop(obj, x, T(2)) == true);
107 assert(obj.compare_exchange_weak(x, T(1)) == false);
111 assert(obj.compare_exchange_strong(x, T(1)) == true);
114 assert(obj.compare_exchange_strong(x, T(0)) == false);
117 assert((obj = T(0)) == T(0));
119 obj = T(2*sizeof(X));
120 assert((obj += std::ptrdiff_t(3)) == T(5*sizeof(X)));
121 assert(obj == T(5*sizeof(X)));
122 assert((obj -= std::ptrdiff_t(3)) == T(2*sizeof(X)));
123 assert(obj == T(2*sizeof(X)));
126 TEST_ALIGNAS_TYPE(A) char storage[sizeof(A)] = {23};
127 A& zero = *new (storage) A();
128 assert(zero == T(0));
133 template <class A, class T>
137 do_test<volatile A, T>();
142 test<std::atomic<int*>, int*>();