123 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// REQUIRES: diagnose-if-support10 11// <atomic>12 13// Test that invalid memory order arguments are diagnosed where possible.14 15#include <atomic>16 17void f() {18 std::atomic<int> x(42);19 volatile std::atomic<int>& vx = x;20 int val1 = 1; ((void)val1);21 int val2 = 2; ((void)val2);22 // load operations23 {24 x.load(std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}25 x.load(std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}26 vx.load(std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}27 vx.load(std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}28 // valid memory orders29 x.load(std::memory_order_relaxed);30 x.load(std::memory_order_consume);31 x.load(std::memory_order_acquire);32 x.load(std::memory_order_seq_cst);33 }34 {35 std::atomic_load_explicit(&x, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}36 std::atomic_load_explicit(&x, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}37 std::atomic_load_explicit(&vx, std::memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}38 std::atomic_load_explicit(&vx, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}39 // valid memory orders40 std::atomic_load_explicit(&x, std::memory_order_relaxed);41 std::atomic_load_explicit(&x, std::memory_order_consume);42 std::atomic_load_explicit(&x, std::memory_order_acquire);43 std::atomic_load_explicit(&x, std::memory_order_seq_cst);44 }45 // store operations46 {47 x.store(42, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}}48 x.store(42, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}}49 x.store(42, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}50 vx.store(42, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}}51 vx.store(42, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}}52 vx.store(42, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}53 // valid memory orders54 x.store(42, std::memory_order_relaxed);55 x.store(42, std::memory_order_release);56 x.store(42, std::memory_order_seq_cst);57 }58 {59 std::atomic_store_explicit(&x, 42, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}}60 std::atomic_store_explicit(&x, 42, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}}61 std::atomic_store_explicit(&x, 42, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}62 std::atomic_store_explicit(&vx, 42, std::memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}}63 std::atomic_store_explicit(&vx, 42, std::memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}}64 std::atomic_store_explicit(&vx, 42, std::memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}65 // valid memory orders66 std::atomic_store_explicit(&x, 42, std::memory_order_relaxed);67 std::atomic_store_explicit(&x, 42, std::memory_order_release);68 std::atomic_store_explicit(&x, 42, std::memory_order_seq_cst);69 }70 // compare exchange weak71 {72 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}}73 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}}74 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}}75 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}}76 // valid memory orders77 x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed);78 x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_consume);79 x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_acquire);80 x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst);81 // Test that the cmpxchg overload with only one memory order argument82 // does not generate any diagnostics.83 x.compare_exchange_weak(val1, val2, std::memory_order_release);84 }85 {86 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}}87 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}}88 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}}89 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}}90 // valid memory orders91 std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed);92 std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_consume);93 std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_acquire);94 std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst);95 }96 // compare exchange strong97 {98 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}}99 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}}100 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}}101 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}}102 // valid memory orders103 x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed);104 x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_consume);105 x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_acquire);106 x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst);107 // Test that the cmpxchg overload with only one memory order argument108 // does not generate any diagnostics.109 x.compare_exchange_strong(val1, val2, std::memory_order_release);110 }111 {112 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}}113 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}}114 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}}115 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}}116 // valid memory orders117 std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed);118 std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_consume);119 std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_acquire);120 std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst);121 }122}123