PR libstdc++/88996 Implement P0439R0
authorEdward Smith-Rowland <3dw4rd@verizon.net>
Mon, 4 Mar 2019 20:11:14 +0000 (20:11 +0000)
committerEdward Smith-Rowland <emsr@gcc.gnu.org>
Mon, 4 Mar 2019 20:11:14 +0000 (20:11 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/atomic_base.h
libstdc++-v3/testsuite/29_atomics/headers/atomic/types_std_c++2a.cc [new file with mode: 0644]
libstdc++-v3/testsuite/29_atomics/headers/atomic/types_std_c++2a_neg.cc [new file with mode: 0644]

index 0fdd76763c9c59eb28b4db2957737f702e8b318f..1d3c7774fd9c142950bac8f910216a29d0e7f54b 100644 (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
index fd2ea7180154e187b0cbf1bac41c002c88f73801..6c1703aa11aadf87623168be1bb1ced3830ef244 100644 (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
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 (file)
index 0000000..60fb6fa
--- /dev/null
@@ -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;
+}
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 (file)
index 0000000..03f5632
--- /dev/null
@@ -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" }
+}