Home | History | Annotate | Download | only in atomics
      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