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 // REQUIRES: verify-support, diagnose-if-support 11 // UNSUPPORTED: libcpp-has-no-threads 12 13 // <atomic> 14 15 // Test that invalid memory order arguments are diagnosed where possible. 16 17 #include <atomic> 18 19 int main() { 20 std::atomic<int> x(42); 21 volatile std::atomic<int>& vx = x; 22 int val1 = 1; ((void)val1); 23 int val2 = 2; ((void)val2); 24 // load operations 25 { 26 x.load(std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}} 27 x.load(std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}} 28 vx.load(std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}} 29 vx.load(std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}} 30 // valid memory orders 31 x.load(std::memory_order_relaxed); 32 x.load(std::memory_order_consume); 33 x.load(std::memory_order_acquire); 34 x.load(std::memory_order_seq_cst); 35 } 36 { 37 std::atomic_load_explicit(&x, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}} 38 std::atomic_load_explicit(&x, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}} 39 std::atomic_load_explicit(&vx, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}} 40 std::atomic_load_explicit(&vx, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}} 41 // valid memory orders 42 std::atomic_load_explicit(&x, std::memory_order_relaxed); 43 std::atomic_load_explicit(&x, std::memory_order_consume); 44 std::atomic_load_explicit(&x, std::memory_order_acquire); 45 std::atomic_load_explicit(&x, std::memory_order_seq_cst); 46 } 47 // store operations 48 { 49 x.store(42, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}} 50 x.store(42, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}} 51 x.store(42, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}} 52 vx.store(42, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}} 53 vx.store(42, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}} 54 vx.store(42, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}} 55 // valid memory orders 56 x.store(42, std::memory_order_relaxed); 57 x.store(42, std::memory_order_release); 58 x.store(42, std::memory_order_seq_cst); 59 } 60 { 61 std::atomic_store_explicit(&x, 42, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}} 62 std::atomic_store_explicit(&x, 42, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}} 63 std::atomic_store_explicit(&x, 42, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}} 64 std::atomic_store_explicit(&vx, 42, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}} 65 std::atomic_store_explicit(&vx, 42, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}} 66 std::atomic_store_explicit(&vx, 42, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}} 67 // valid memory orders 68 std::atomic_store_explicit(&x, 42, std::memory_order_relaxed); 69 std::atomic_store_explicit(&x, 42, std::memory_order_release); 70 std::atomic_store_explicit(&x, 42, std::memory_order_seq_cst); 71 } 72 // compare exchange weak 73 { 74 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}} 75 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}} 76 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}} 77 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}} 78 // valid memory orders 79 x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed); 80 x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_consume); 81 x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_acquire); 82 x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst); 83 // Test that the cmpxchg overload with only one memory order argument 84 // does not generate any diagnostics. 85 x.compare_exchange_weak(val1, val2, std::memory_order_release); 86 } 87 { 88 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}} 89 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}} 90 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}} 91 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}} 92 // valid memory orders 93 std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed); 94 std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_consume); 95 std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_acquire); 96 std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst); 97 } 98 // compare exchange strong 99 { 100 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}} 101 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}} 102 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}} 103 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}} 104 // valid memory orders 105 x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed); 106 x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_consume); 107 x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_acquire); 108 x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst); 109 // Test that the cmpxchg overload with only one memory order argument 110 // does not generate any diagnostics. 111 x.compare_exchange_strong(val1, val2, std::memory_order_release); 112 } 113 { 114 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}} 115 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}} 116 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}} 117 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}} 118 // valid memory orders 119 std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed); 120 std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_consume); 121 std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_acquire); 122 std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst); 123 } 124 } 125