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:
Eric Fiselier 2016-07-23 01:43:53 +00:00
parent 586b16e16a
commit 6f4a165e51
2 changed files with 0 additions and 203 deletions

View File

@ -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>

View File

@ -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);
}
}