1 //===----------------------------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // This test fails because diagnose_if doesn't emit all of the diagnostics
11 // when -fdelayed-template-parsing is enabled, like it is on Windows.
12 // XFAIL: LIBCXX-WINDOWS-FIXME
13
14 // REQUIRES: verify-support, diagnose-if-support
15 // UNSUPPORTED: libcpp-has-no-threads
16
17 // <atomic>
18
19 // Test that invalid memory order arguments are diagnosed where possible.
20
21 #include <atomic>
22
main()23 int main() {
24 std::atomic<int> x(42);
25 volatile std::atomic<int>& vx = x;
26 int val1 = 1; ((void)val1);
27 int val2 = 2; ((void)val2);
28 // load operations
29 {
30 x.load(std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
31 x.load(std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
32 vx.load(std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
33 vx.load(std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
34 // valid memory orders
35 x.load(std::memory_order_relaxed);
36 x.load(std::memory_order_consume);
37 x.load(std::memory_order_acquire);
38 x.load(std::memory_order_seq_cst);
39 }
40 {
41 std::atomic_load_explicit(&x, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
42 std::atomic_load_explicit(&x, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
43 std::atomic_load_explicit(&vx, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
44 std::atomic_load_explicit(&vx, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
45 // valid memory orders
46 std::atomic_load_explicit(&x, std::memory_order_relaxed);
47 std::atomic_load_explicit(&x, std::memory_order_consume);
48 std::atomic_load_explicit(&x, std::memory_order_acquire);
49 std::atomic_load_explicit(&x, std::memory_order_seq_cst);
50 }
51 // store operations
52 {
53 x.store(42, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}}
54 x.store(42, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}}
55 x.store(42, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
56 vx.store(42, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}}
57 vx.store(42, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}}
58 vx.store(42, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
59 // valid memory orders
60 x.store(42, std::memory_order_relaxed);
61 x.store(42, std::memory_order_release);
62 x.store(42, std::memory_order_seq_cst);
63 }
64 {
65 std::atomic_store_explicit(&x, 42, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}}
66 std::atomic_store_explicit(&x, 42, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}}
67 std::atomic_store_explicit(&x, 42, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
68 std::atomic_store_explicit(&vx, 42, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}}
69 std::atomic_store_explicit(&vx, 42, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}}
70 std::atomic_store_explicit(&vx, 42, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
71 // valid memory orders
72 std::atomic_store_explicit(&x, 42, std::memory_order_relaxed);
73 std::atomic_store_explicit(&x, 42, std::memory_order_release);
74 std::atomic_store_explicit(&x, 42, std::memory_order_seq_cst);
75 }
76 // compare exchange weak
77 {
78 x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
79 x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
80 vx.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
81 vx.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
82 // valid memory orders
83 x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed);
84 x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_consume);
85 x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_acquire);
86 x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst);
87 // Test that the cmpxchg overload with only one memory order argument
88 // does not generate any diagnostics.
89 x.compare_exchange_weak(val1, val2, std::memory_order_release);
90 }
91 {
92 std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
93 std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
94 std::atomic_compare_exchange_weak_explicit(&vx, &val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
95 std::atomic_compare_exchange_weak_explicit(&vx, &val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
96 // valid memory orders
97 std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed);
98 std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_consume);
99 std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_acquire);
100 std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst);
101 }
102 // compare exchange strong
103 {
104 x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
105 x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
106 vx.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
107 vx.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
108 // valid memory orders
109 x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed);
110 x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_consume);
111 x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_acquire);
112 x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst);
113 // Test that the cmpxchg overload with only one memory order argument
114 // does not generate any diagnostics.
115 x.compare_exchange_strong(val1, val2, std::memory_order_release);
116 }
117 {
118 std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
119 std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
120 std::atomic_compare_exchange_strong_explicit(&vx, &val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
121 std::atomic_compare_exchange_strong_explicit(&vx, &val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
122 // valid memory orders
123 std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed);
124 std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_consume);
125 std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_acquire);
126 std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst);
127 }
128 }
129