From: Edward Smith-Rowland <3dw4rd@verizon.net> Date: Mon, 4 Mar 2019 20:11:14 +0000 (+0000) Subject: PR libstdc++/88996 Implement P0439R0 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=94014ee95b2594859168baac31da4c846a256807;p=gcc.git 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 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 0fdd76763c9..1d3c7774fd9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -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 * testsuite/26_numerics/bit/bitops.rot/rotl.cc: Remove bogus dg-do diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h index fd2ea718015..6c1703aa11a 100644 --- a/libstdc++-v3/include/bits/atomic_base.h +++ b/libstdc++-v3/include/bits/atomic_base.h @@ -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 @@ -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 diff --git a/libstdc++-v3/testsuite/29_atomics/headers/atomic/types_std_c++2a.cc b/libstdc++-v3/testsuite/29_atomics/headers/atomic/types_std_c++2a.cc new file mode 100644 index 00000000000..60fb6faba89 --- /dev/null +++ b/libstdc++-v3/testsuite/29_atomics/headers/atomic/types_std_c++2a.cc @@ -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 +// . + +#include + +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; +} diff --git a/libstdc++-v3/testsuite/29_atomics/headers/atomic/types_std_c++2a_neg.cc b/libstdc++-v3/testsuite/29_atomics/headers/atomic/types_std_c++2a_neg.cc new file mode 100644 index 00000000000..03f56320074 --- /dev/null +++ b/libstdc++-v3/testsuite/29_atomics/headers/atomic/types_std_c++2a_neg.cc @@ -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 +// . + +#include + +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" } +}