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// UNSUPPORTED: libcpp-has-no-threads
11
12// This test verifies behavior specified by [atomics.types.operations.req]/21:
13//
14//     When only one memory_order argument is supplied, the value of success is
15//     order, and the value of failure is order except that a value of
16//     memory_order_acq_rel shall be replaced by the value memory_order_acquire
17//     and a value of memory_order_release shall be replaced by the value
18//     memory_order_relaxed.
19//
20// Clang's atomic intrinsics do this for us, but GCC's do not. We don't actually
21// have visibility to see what these memory orders are lowered to, but we can at
22// least check that they are lowered at all (otherwise there is a compile
23// failure with GCC).
24
25#include <atomic>
26
27int main() {
28    std::atomic<int> i;
29    volatile std::atomic<int> v;
30    int exp = 0;
31
32    i.compare_exchange_weak(exp, 0, std::memory_order_acq_rel);
33    i.compare_exchange_weak(exp, 0, std::memory_order_release);
34    i.compare_exchange_strong(exp, 0, std::memory_order_acq_rel);
35    i.compare_exchange_strong(exp, 0, std::memory_order_release);
36
37    v.compare_exchange_weak(exp, 0, std::memory_order_acq_rel);
38    v.compare_exchange_weak(exp, 0, std::memory_order_release);
39    v.compare_exchange_strong(exp, 0, std::memory_order_acq_rel);
40    v.compare_exchange_strong(exp, 0, std::memory_order_release);
41
42    return 0;
43}
44