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
|
# define __cpp_lib_atomic_is_always_lock_free 201603L
|
||||||
#endif
|
#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
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||||
|
|
||||||
typedef enum memory_order
|
typedef enum memory_order
|
||||||
|
@ -956,21 +933,6 @@ struct __atomic_base // false
|
||||||
bool compare_exchange_strong(_Tp& __e, _Tp __d,
|
bool compare_exchange_strong(_Tp& __e, _Tp __d,
|
||||||
memory_order __m = memory_order_seq_cst) _NOEXCEPT
|
memory_order __m = memory_order_seq_cst) _NOEXCEPT
|
||||||
{return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
|
{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
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
|
#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);
|
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
|
// atomic_fetch_add
|
||||||
|
|
||||||
template <class _Tp>
|
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