PR libstdc++/88996 Implement P0439R0
2019-03-04 Edward Smith-Rowland <3dw4rd@verizon.net> PR libstdc++/88996 Implement P0439R0 Make std::memory_order a scoped enumeration. * include/bits/atomic_base.h: For C++20 make memory_order a scoped enum, add variables for the old enumerators. Adjust calls. * testsuite/29_atomics/headers/atomic/types_std_c++2a.cc: New test. * testsuite/29_atomics/headers/atomic/types_std_c++2a_neg.cc: New test. From-SVN: r269372
This commit is contained in:
parent
f0103f7bb0
commit
94014ee95b
@ -1,3 +1,12 @@
|
||||
2019-03-04 Edward Smith-Rowland <3dw4rd@verizon.net>
|
||||
|
||||
PR libstdc++/88996 Implement P0439R0
|
||||
Make std::memory_order a scoped enumeration.
|
||||
* include/bits/atomic_base.h: For C++20 make memory_order a scoped enum,
|
||||
add variables for the old enumerators. Adjust calls.
|
||||
* testsuite/29_atomics/headers/atomic/types_std_c++2a.cc: New test.
|
||||
* testsuite/29_atomics/headers/atomic/types_std_c++2a_neg.cc: New test.
|
||||
|
||||
2019-03-04 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* testsuite/26_numerics/bit/bitops.rot/rotl.cc: Remove bogus dg-do
|
||||
|
@ -52,6 +52,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
*/
|
||||
|
||||
/// Enumeration for memory_order
|
||||
#if __cplusplus > 201703L
|
||||
enum class memory_order : int
|
||||
{
|
||||
relaxed,
|
||||
consume,
|
||||
acquire,
|
||||
release,
|
||||
acq_rel,
|
||||
seq_cst
|
||||
};
|
||||
|
||||
inline constexpr memory_order memory_order_relaxed = memory_order::relaxed;
|
||||
inline constexpr memory_order memory_order_consume = memory_order::consume;
|
||||
inline constexpr memory_order memory_order_acquire = memory_order::acquire;
|
||||
inline constexpr memory_order memory_order_release = memory_order::release;
|
||||
inline constexpr memory_order memory_order_acq_rel = memory_order::acq_rel;
|
||||
inline constexpr memory_order memory_order_seq_cst = memory_order::seq_cst;
|
||||
#else
|
||||
typedef enum memory_order
|
||||
{
|
||||
memory_order_relaxed,
|
||||
@ -61,6 +79,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
memory_order_acq_rel,
|
||||
memory_order_seq_cst
|
||||
} memory_order;
|
||||
#endif
|
||||
|
||||
enum __memory_order_modifier
|
||||
{
|
||||
@ -73,13 +92,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
constexpr memory_order
|
||||
operator|(memory_order __m, __memory_order_modifier __mod)
|
||||
{
|
||||
return memory_order(__m | int(__mod));
|
||||
return memory_order(int(__m) | int(__mod));
|
||||
}
|
||||
|
||||
constexpr memory_order
|
||||
operator&(memory_order __m, __memory_order_modifier __mod)
|
||||
{
|
||||
return memory_order(__m & int(__mod));
|
||||
return memory_order(int(__m) & int(__mod));
|
||||
}
|
||||
|
||||
// Drop release ordering as per [atomics.types.operations.req]/21
|
||||
@ -94,16 +113,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__cmpexch_failure_order(memory_order __m) noexcept
|
||||
{
|
||||
return memory_order(__cmpexch_failure_order2(__m & __memory_order_mask)
|
||||
| (__m & __memory_order_modifier_mask));
|
||||
| __memory_order_modifier(__m & __memory_order_modifier_mask));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE void
|
||||
atomic_thread_fence(memory_order __m) noexcept
|
||||
{ __atomic_thread_fence(__m); }
|
||||
{ __atomic_thread_fence(int(__m)); }
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE void
|
||||
atomic_signal_fence(memory_order __m) noexcept
|
||||
{ __atomic_signal_fence(__m); }
|
||||
{ __atomic_signal_fence(int(__m)); }
|
||||
|
||||
/// kill_dependency
|
||||
template<typename _Tp>
|
||||
@ -173,13 +192,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
_GLIBCXX_ALWAYS_INLINE bool
|
||||
test_and_set(memory_order __m = memory_order_seq_cst) noexcept
|
||||
{
|
||||
return __atomic_test_and_set (&_M_i, __m);
|
||||
return __atomic_test_and_set (&_M_i, int(__m));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE bool
|
||||
test_and_set(memory_order __m = memory_order_seq_cst) volatile noexcept
|
||||
{
|
||||
return __atomic_test_and_set (&_M_i, __m);
|
||||
return __atomic_test_and_set (&_M_i, int(__m));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE void
|
||||
@ -190,7 +209,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__b != memory_order_acquire);
|
||||
__glibcxx_assert(__b != memory_order_acq_rel);
|
||||
|
||||
__atomic_clear (&_M_i, __m);
|
||||
__atomic_clear (&_M_i, int(__m));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE void
|
||||
@ -201,7 +220,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__b != memory_order_acquire);
|
||||
__glibcxx_assert(__b != memory_order_acq_rel);
|
||||
|
||||
__atomic_clear (&_M_i, __m);
|
||||
__atomic_clear (&_M_i, int(__m));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -375,7 +394,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__b != memory_order_acq_rel);
|
||||
__glibcxx_assert(__b != memory_order_consume);
|
||||
|
||||
__atomic_store_n(&_M_i, __i, __m);
|
||||
__atomic_store_n(&_M_i, __i, int(__m));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE void
|
||||
@ -387,7 +406,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__b != memory_order_acq_rel);
|
||||
__glibcxx_assert(__b != memory_order_consume);
|
||||
|
||||
__atomic_store_n(&_M_i, __i, __m);
|
||||
__atomic_store_n(&_M_i, __i, int(__m));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __int_type
|
||||
@ -397,7 +416,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__b != memory_order_release);
|
||||
__glibcxx_assert(__b != memory_order_acq_rel);
|
||||
|
||||
return __atomic_load_n(&_M_i, __m);
|
||||
return __atomic_load_n(&_M_i, int(__m));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __int_type
|
||||
@ -407,14 +426,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__b != memory_order_release);
|
||||
__glibcxx_assert(__b != memory_order_acq_rel);
|
||||
|
||||
return __atomic_load_n(&_M_i, __m);
|
||||
return __atomic_load_n(&_M_i, int(__m));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __int_type
|
||||
exchange(__int_type __i,
|
||||
memory_order __m = memory_order_seq_cst) noexcept
|
||||
{
|
||||
return __atomic_exchange_n(&_M_i, __i, __m);
|
||||
return __atomic_exchange_n(&_M_i, __i, int(__m));
|
||||
}
|
||||
|
||||
|
||||
@ -422,7 +441,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
exchange(__int_type __i,
|
||||
memory_order __m = memory_order_seq_cst) volatile noexcept
|
||||
{
|
||||
return __atomic_exchange_n(&_M_i, __i, __m);
|
||||
return __atomic_exchange_n(&_M_i, __i, int(__m));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE bool
|
||||
@ -435,7 +454,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__b2 != memory_order_acq_rel);
|
||||
__glibcxx_assert(__b2 <= __b1);
|
||||
|
||||
return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2);
|
||||
return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1,
|
||||
int(__m1), int(__m2));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE bool
|
||||
@ -449,7 +469,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__b2 != memory_order_acq_rel);
|
||||
__glibcxx_assert(__b2 <= __b1);
|
||||
|
||||
return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2);
|
||||
return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1,
|
||||
int(__m1), int(__m2));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE bool
|
||||
@ -478,7 +499,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__b2 != memory_order_acq_rel);
|
||||
__glibcxx_assert(__b2 <= __b1);
|
||||
|
||||
return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
|
||||
return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0,
|
||||
int(__m1), int(__m2));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE bool
|
||||
@ -493,7 +515,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__b2 != memory_order_acq_rel);
|
||||
__glibcxx_assert(__b2 <= __b1);
|
||||
|
||||
return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
|
||||
return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0,
|
||||
int(__m1), int(__m2));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE bool
|
||||
@ -515,52 +538,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
_GLIBCXX_ALWAYS_INLINE __int_type
|
||||
fetch_add(__int_type __i,
|
||||
memory_order __m = memory_order_seq_cst) noexcept
|
||||
{ return __atomic_fetch_add(&_M_i, __i, __m); }
|
||||
{ return __atomic_fetch_add(&_M_i, __i, int(__m)); }
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __int_type
|
||||
fetch_add(__int_type __i,
|
||||
memory_order __m = memory_order_seq_cst) volatile noexcept
|
||||
{ return __atomic_fetch_add(&_M_i, __i, __m); }
|
||||
{ return __atomic_fetch_add(&_M_i, __i, int(__m)); }
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __int_type
|
||||
fetch_sub(__int_type __i,
|
||||
memory_order __m = memory_order_seq_cst) noexcept
|
||||
{ return __atomic_fetch_sub(&_M_i, __i, __m); }
|
||||
{ return __atomic_fetch_sub(&_M_i, __i, int(__m)); }
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __int_type
|
||||
fetch_sub(__int_type __i,
|
||||
memory_order __m = memory_order_seq_cst) volatile noexcept
|
||||
{ return __atomic_fetch_sub(&_M_i, __i, __m); }
|
||||
{ return __atomic_fetch_sub(&_M_i, __i, int(__m)); }
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __int_type
|
||||
fetch_and(__int_type __i,
|
||||
memory_order __m = memory_order_seq_cst) noexcept
|
||||
{ return __atomic_fetch_and(&_M_i, __i, __m); }
|
||||
{ return __atomic_fetch_and(&_M_i, __i, int(__m)); }
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __int_type
|
||||
fetch_and(__int_type __i,
|
||||
memory_order __m = memory_order_seq_cst) volatile noexcept
|
||||
{ return __atomic_fetch_and(&_M_i, __i, __m); }
|
||||
{ return __atomic_fetch_and(&_M_i, __i, int(__m)); }
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __int_type
|
||||
fetch_or(__int_type __i,
|
||||
memory_order __m = memory_order_seq_cst) noexcept
|
||||
{ return __atomic_fetch_or(&_M_i, __i, __m); }
|
||||
{ return __atomic_fetch_or(&_M_i, __i, int(__m)); }
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __int_type
|
||||
fetch_or(__int_type __i,
|
||||
memory_order __m = memory_order_seq_cst) volatile noexcept
|
||||
{ return __atomic_fetch_or(&_M_i, __i, __m); }
|
||||
{ return __atomic_fetch_or(&_M_i, __i, int(__m)); }
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __int_type
|
||||
fetch_xor(__int_type __i,
|
||||
memory_order __m = memory_order_seq_cst) noexcept
|
||||
{ return __atomic_fetch_xor(&_M_i, __i, __m); }
|
||||
{ return __atomic_fetch_xor(&_M_i, __i, int(__m)); }
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __int_type
|
||||
fetch_xor(__int_type __i,
|
||||
memory_order __m = memory_order_seq_cst) volatile noexcept
|
||||
{ return __atomic_fetch_xor(&_M_i, __i, __m); }
|
||||
{ return __atomic_fetch_xor(&_M_i, __i, int(__m)); }
|
||||
};
|
||||
|
||||
|
||||
@ -692,7 +715,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__b != memory_order_acq_rel);
|
||||
__glibcxx_assert(__b != memory_order_consume);
|
||||
|
||||
__atomic_store_n(&_M_p, __p, __m);
|
||||
__atomic_store_n(&_M_p, __p, int(__m));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE void
|
||||
@ -704,7 +727,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__b != memory_order_acq_rel);
|
||||
__glibcxx_assert(__b != memory_order_consume);
|
||||
|
||||
__atomic_store_n(&_M_p, __p, __m);
|
||||
__atomic_store_n(&_M_p, __p, int(__m));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __pointer_type
|
||||
@ -714,7 +737,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__b != memory_order_release);
|
||||
__glibcxx_assert(__b != memory_order_acq_rel);
|
||||
|
||||
return __atomic_load_n(&_M_p, __m);
|
||||
return __atomic_load_n(&_M_p, int(__m));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __pointer_type
|
||||
@ -724,14 +747,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__b != memory_order_release);
|
||||
__glibcxx_assert(__b != memory_order_acq_rel);
|
||||
|
||||
return __atomic_load_n(&_M_p, __m);
|
||||
return __atomic_load_n(&_M_p, int(__m));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __pointer_type
|
||||
exchange(__pointer_type __p,
|
||||
memory_order __m = memory_order_seq_cst) noexcept
|
||||
{
|
||||
return __atomic_exchange_n(&_M_p, __p, __m);
|
||||
return __atomic_exchange_n(&_M_p, __p, int(__m));
|
||||
}
|
||||
|
||||
|
||||
@ -739,7 +762,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
exchange(__pointer_type __p,
|
||||
memory_order __m = memory_order_seq_cst) volatile noexcept
|
||||
{
|
||||
return __atomic_exchange_n(&_M_p, __p, __m);
|
||||
return __atomic_exchange_n(&_M_p, __p, int(__m));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE bool
|
||||
@ -753,7 +776,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__b2 != memory_order_acq_rel);
|
||||
__glibcxx_assert(__b2 <= __b1);
|
||||
|
||||
return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2);
|
||||
return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0,
|
||||
int(__m1), int(__m2));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE bool
|
||||
@ -768,28 +792,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
__glibcxx_assert(__b2 != memory_order_acq_rel);
|
||||
__glibcxx_assert(__b2 <= __b1);
|
||||
|
||||
return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2);
|
||||
return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0,
|
||||
int(__m1), int(__m2));
|
||||
}
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __pointer_type
|
||||
fetch_add(ptrdiff_t __d,
|
||||
memory_order __m = memory_order_seq_cst) noexcept
|
||||
{ return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
|
||||
{ return __atomic_fetch_add(&_M_p, _M_type_size(__d), int(__m)); }
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __pointer_type
|
||||
fetch_add(ptrdiff_t __d,
|
||||
memory_order __m = memory_order_seq_cst) volatile noexcept
|
||||
{ return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
|
||||
{ return __atomic_fetch_add(&_M_p, _M_type_size(__d), int(__m)); }
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __pointer_type
|
||||
fetch_sub(ptrdiff_t __d,
|
||||
memory_order __m = memory_order_seq_cst) noexcept
|
||||
{ return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
|
||||
{ return __atomic_fetch_sub(&_M_p, _M_type_size(__d), int(__m)); }
|
||||
|
||||
_GLIBCXX_ALWAYS_INLINE __pointer_type
|
||||
fetch_sub(ptrdiff_t __d,
|
||||
memory_order __m = memory_order_seq_cst) volatile noexcept
|
||||
{ return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
|
||||
{ return __atomic_fetch_sub(&_M_p, _M_type_size(__d), int(__m)); }
|
||||
};
|
||||
|
||||
// @} group atomics
|
||||
|
@ -0,0 +1,32 @@
|
||||
// { dg-options "-std=gnu++2a" }
|
||||
// { dg-do compile { target c++2a } }
|
||||
|
||||
// Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <atomic>
|
||||
|
||||
void test01()
|
||||
{
|
||||
using std::memory_order;
|
||||
constexpr auto relaxed = memory_order::relaxed;
|
||||
constexpr auto consume = memory_order::consume;
|
||||
constexpr auto acquire = memory_order::acquire;
|
||||
constexpr auto release = memory_order::release;
|
||||
constexpr auto acq_rel = memory_order::acq_rel;
|
||||
constexpr auto seq_cst = memory_order::seq_cst;
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
// { dg-options "-std=gnu++2a" }
|
||||
// { dg-do compile { target c++2a } }
|
||||
|
||||
// Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <atomic>
|
||||
|
||||
void test01()
|
||||
{
|
||||
// Not global scoped, only namespace std.
|
||||
using memory_order; // { dg-error "expected nested-name-specifier" }
|
||||
constexpr auto relaxed = memory_order::relaxed; // { dg-error "has not been declared" }
|
||||
constexpr auto consume = memory_order::consume; // { dg-error "has not been declared" }
|
||||
constexpr auto acquire = memory_order::acquire; // { dg-error "has not been declared" }
|
||||
constexpr auto release = memory_order::release; // { dg-error "has not been declared" }
|
||||
constexpr auto acq_rel = memory_order::acq_rel; // { dg-error "has not been declared" }
|
||||
constexpr auto seq_cst = memory_order::seq_cst; // { dg-error "has not been declared" }
|
||||
}
|
Loading…
Reference in New Issue
Block a user