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