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:
Edward Smith-Rowland 2019-03-04 20:11:14 +00:00 committed by Edward Smith-Rowland
parent f0103f7bb0
commit 94014ee95b
4 changed files with 140 additions and 41 deletions

View File

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

View File

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

View File

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

View File

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