forked from OSchip/llvm-project
Revert r276506 - Diagnose invalid memory order arguments in <atomic>.
There is a bug in Clang 3.6 and earlier that causes compile failures. I suspect it's due to the usage of member function parameter names in the attributes. llvm-svn: 276507
This commit is contained in:
parent
586b16e16a
commit
6f4a165e51
|
@ -560,29 +560,6 @@ void atomic_signal_fence(memory_order m) noexcept;
|
|||
# define __cpp_lib_atomic_is_always_lock_free 201603L
|
||||
#endif
|
||||
|
||||
|
||||
#if __has_attribute(__enable_if__) && __has_attribute(__unavailable__)
|
||||
# define _LIBCPP_CHECK_ATOMIC_MEMORY_ORDER
|
||||
# define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
|
||||
__attribute__ ((__enable_if__(__m == memory_order_release \
|
||||
|| __m == memory_order_acq_rel, ""))) \
|
||||
__attribute__ ((__unavailable__("memory order argument to atomic operation is invalid")))
|
||||
|
||||
# define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
|
||||
__attribute__ ((__enable_if__(__m == memory_order_consume \
|
||||
|| __m == memory_order_acquire \
|
||||
|| __m == memory_order_acq_rel, ""))) \
|
||||
__attribute__ ((__unavailable__("memory order argument to atomic operation is invalid")))
|
||||
|
||||
// Note that this is not checking the 'stronger' requirement.
|
||||
// See wg21.link/p0418
|
||||
# define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) \
|
||||
__attribute__ ((__enable_if__(__f == memory_order_release \
|
||||
|| __f == memory_order_acq_rel, ""))) \
|
||||
__attribute__ ((__unavailable__("memory order argument to atomic operation is invalid")))
|
||||
#endif
|
||||
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
typedef enum memory_order
|
||||
|
@ -956,21 +933,6 @@ struct __atomic_base // false
|
|||
bool compare_exchange_strong(_Tp& __e, _Tp __d,
|
||||
memory_order __m = memory_order_seq_cst) _NOEXCEPT
|
||||
{return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
|
||||
#if defined(_LIBCPP_CHECK_ATOMIC_MEMORY_ORDER)
|
||||
void store(_Tp __d, memory_order __m) volatile _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m);
|
||||
void store(_Tp __d, memory_order __m) _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m);
|
||||
|
||||
_Tp load(memory_order __m) const volatile _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m);
|
||||
_Tp load(memory_order __m) const _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m);
|
||||
bool compare_exchange_weak(_Tp&, _Tp, memory_order __s, memory_order __f) volatile
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f);
|
||||
bool compare_exchange_weak(_Tp&, _Tp, memory_order __s, memory_order __f)
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f);
|
||||
bool compare_exchange_strong(_Tp&, _Tp, memory_order __s, memory_order __f) volatile
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f);
|
||||
bool compare_exchange_strong(_Tp&, _Tp, memory_order __s, memory_order __f)
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f);
|
||||
#endif
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
|
||||
|
@ -1382,46 +1344,6 @@ atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
|
|||
return __o->compare_exchange_strong(*__e, __d, __s, __f);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _LIBCPP_CHECK_ATOMIC_MEMORY_ORDER
|
||||
template <class _Tp>
|
||||
void atomic_store_explicit(volatile atomic<_Tp>*, _Tp, memory_order __m)
|
||||
_LIBCPP_CHECK_STORE_MEMORY_ORDER(__m);
|
||||
|
||||
template <class _Tp>
|
||||
void atomic_store_explicit(atomic<_Tp>*, _Tp, memory_order __m)
|
||||
_LIBCPP_CHECK_STORE_MEMORY_ORDER(__m);
|
||||
|
||||
template <class _Tp>
|
||||
_Tp atomic_load_explicit(const volatile atomic<_Tp>*, memory_order __m)
|
||||
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m);
|
||||
|
||||
template <class _Tp>
|
||||
_Tp atomic_load_explicit(const atomic<_Tp>*, memory_order __m)
|
||||
_LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m);
|
||||
|
||||
template <class _Tp>
|
||||
bool atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>*, _Tp*, _Tp,
|
||||
memory_order __s, memory_order __f)
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f);
|
||||
|
||||
template <class _Tp>
|
||||
bool atomic_compare_exchange_weak_explicit(atomic<_Tp>*, _Tp*, _Tp,
|
||||
memory_order __s, memory_order __f)
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f);
|
||||
|
||||
template <class _Tp>
|
||||
bool atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>*, _Tp*, _Tp,
|
||||
memory_order __s, memory_order __f)
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f);
|
||||
|
||||
template <class _Tp>
|
||||
bool atomic_compare_exchange_strong_explicit(atomic<_Tp>*, _Tp*, _Tp,
|
||||
memory_order __s, memory_order __f)
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f);
|
||||
|
||||
#endif
|
||||
|
||||
// atomic_fetch_add
|
||||
|
||||
template <class _Tp>
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// The attributes used to diagnose incorrect memory order inputs is clang
|
||||
// specific.
|
||||
// UNSUPPORTED: gcc
|
||||
|
||||
// <atomic>
|
||||
|
||||
// Test that invalid memory order arguments are diagnosed where possible.
|
||||
|
||||
#include <atomic>
|
||||
|
||||
int main() {
|
||||
std::atomic<int> x(42);
|
||||
volatile std::atomic<int>& vx = x;
|
||||
int val1 = 1;
|
||||
int val2 = 2;
|
||||
// load operations
|
||||
{
|
||||
x.load(std::memory_order_release); // expected-error {{operation is invalid}}
|
||||
x.load(std::memory_order_acq_rel); // expected-error {{operation is invalid}}
|
||||
vx.load(std::memory_order_release); // expected-error {{operation is invalid}}
|
||||
vx.load(std::memory_order_acq_rel); // expected-error {{operation is invalid}}
|
||||
// valid memory orders
|
||||
x.load(std::memory_order_relaxed);
|
||||
x.load(std::memory_order_consume);
|
||||
x.load(std::memory_order_acquire);
|
||||
x.load(std::memory_order_seq_cst);
|
||||
}
|
||||
{
|
||||
std::atomic_load_explicit(&x, std::memory_order_release); // expected-error {{operation is invalid}}
|
||||
std::atomic_load_explicit(&x, std::memory_order_acq_rel); // expected-error {{operation is invalid}}
|
||||
std::atomic_load_explicit(&vx, std::memory_order_release); // expected-error {{operation is invalid}}
|
||||
std::atomic_load_explicit(&vx, std::memory_order_acq_rel); // expected-error {{operation is invalid}}
|
||||
// valid memory orders
|
||||
std::atomic_load_explicit(&x, std::memory_order_relaxed);
|
||||
std::atomic_load_explicit(&x, std::memory_order_consume);
|
||||
std::atomic_load_explicit(&x, std::memory_order_acquire);
|
||||
std::atomic_load_explicit(&x, std::memory_order_seq_cst);
|
||||
}
|
||||
// store operations
|
||||
{
|
||||
x.store(42, std::memory_order_consume); // expected-error {{operation is invalid}}
|
||||
x.store(42, std::memory_order_acquire); // expected-error {{operation is invalid}}
|
||||
x.store(42, std::memory_order_acq_rel); // expected-error {{operation is invalid}}
|
||||
vx.store(42, std::memory_order_consume); // expected-error {{operation is invalid}}
|
||||
vx.store(42, std::memory_order_acquire); // expected-error {{operation is invalid}}
|
||||
vx.store(42, std::memory_order_acq_rel); // expected-error {{operation is invalid}}
|
||||
// valid memory orders
|
||||
x.store(42, std::memory_order_relaxed);
|
||||
x.store(42, std::memory_order_release);
|
||||
x.store(42, std::memory_order_seq_cst);
|
||||
}
|
||||
{
|
||||
std::atomic_store_explicit(&x, 42, std::memory_order_consume); // expected-error {{operation is invalid}}
|
||||
std::atomic_store_explicit(&x, 42, std::memory_order_acquire); // expected-error {{operation is invalid}}
|
||||
std::atomic_store_explicit(&x, 42, std::memory_order_acq_rel); // expected-error {{operation is invalid}}
|
||||
std::atomic_store_explicit(&vx, 42, std::memory_order_consume); // expected-error {{operation is invalid}}
|
||||
std::atomic_store_explicit(&vx, 42, std::memory_order_acquire); // expected-error {{operation is invalid}}
|
||||
std::atomic_store_explicit(&vx, 42, std::memory_order_acq_rel); // expected-error {{operation is invalid}}
|
||||
// valid memory orders
|
||||
std::atomic_store_explicit(&x, 42, std::memory_order_relaxed);
|
||||
std::atomic_store_explicit(&x, 42, std::memory_order_release);
|
||||
std::atomic_store_explicit(&x, 42, std::memory_order_seq_cst);
|
||||
}
|
||||
// compare exchange weak
|
||||
{
|
||||
x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-error {{operation is invalid}}
|
||||
x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-error {{operation is invalid}}
|
||||
vx.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-error {{operation is invalid}}
|
||||
vx.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-error {{operation is invalid}}
|
||||
// valid memory orders
|
||||
x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed);
|
||||
x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_consume);
|
||||
x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_acquire);
|
||||
x.compare_exchange_weak(val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst);
|
||||
// Test that the cmpxchg overload with only one memory order argument
|
||||
// does not generate any diagnostics.
|
||||
x.compare_exchange_weak(val1, val2, std::memory_order_release);
|
||||
}
|
||||
{
|
||||
std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-error {{operation is invalid}}
|
||||
std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-error {{operation is invalid}}
|
||||
std::atomic_compare_exchange_weak_explicit(&vx, &val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-error {{operation is invalid}}
|
||||
std::atomic_compare_exchange_weak_explicit(&vx, &val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-error {{operation is invalid}}
|
||||
// valid memory orders
|
||||
std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed);
|
||||
std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_consume);
|
||||
std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_acquire);
|
||||
std::atomic_compare_exchange_weak_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst);
|
||||
}
|
||||
// compare exchange strong
|
||||
{
|
||||
x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-error {{operation is invalid}}
|
||||
x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-error {{operation is invalid}}
|
||||
vx.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-error {{operation is invalid}}
|
||||
vx.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-error {{operation is invalid}}
|
||||
// valid memory orders
|
||||
x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed);
|
||||
x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_consume);
|
||||
x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_acquire);
|
||||
x.compare_exchange_strong(val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst);
|
||||
// Test that the cmpxchg overload with only one memory order argument
|
||||
// does not generate any diagnostics.
|
||||
x.compare_exchange_strong(val1, val2, std::memory_order_release);
|
||||
}
|
||||
{
|
||||
std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-error {{operation is invalid}}
|
||||
std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-error {{operation is invalid}}
|
||||
std::atomic_compare_exchange_strong_explicit(&vx, &val1, val2, std::memory_order_seq_cst, std::memory_order_release); // expected-error {{operation is invalid}}
|
||||
std::atomic_compare_exchange_strong_explicit(&vx, &val1, val2, std::memory_order_seq_cst, std::memory_order_acq_rel); // expected-error {{operation is invalid}}
|
||||
// valid memory orders
|
||||
std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_relaxed);
|
||||
std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_consume);
|
||||
std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_acquire);
|
||||
std::atomic_compare_exchange_strong_explicit(&x, &val1, val2, std::memory_order_seq_cst, std::memory_order_seq_cst);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue