[libc++] LWG3745 noexcept for atomic_wait.
authorMark de Wever <koraq@xs4all.nl>
Thu, 22 Dec 2022 19:35:36 +0000 (20:35 +0100)
committerMark de Wever <koraq@xs4all.nl>
Fri, 23 Dec 2022 16:17:00 +0000 (17:17 +0100)
The noexcept was already implemented, this only updates the synposis and
adds tests to validate that the functions are noexcept.

This implements:
- LWG3745 std::atomic_wait and its friends lack noexcept

Reviewed By: #libc, philnik

Differential Revision: https://reviews.llvm.org/D140575

libcxx/docs/Status/Cxx2bIssues.csv
libcxx/include/atomic
libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_notify_all.pass.cpp
libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_notify_one.pass.cpp
libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait.pass.cpp
libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait_explicit.pass.cpp

index a793c88..3a6d2c8 100644 (file)
 "`3737 <https://wg21.link/LWG3737>`__","``take_view::sentinel`` should provide ``operator-``", "November 2022","","","|ranges|"
 "`3738 <https://wg21.link/LWG3738>`__","Missing preconditions for ``take_view`` constructor", "November 2022","","","|ranges|"
 "`3743 <https://wg21.link/LWG3743>`__","``ranges::to``'s reserve may be ill-formed", "November 2022","","","|ranges|"
-"`3745 <https://wg21.link/LWG3745>`__","``std::atomic_wait`` and its friends lack ``noexcept``", "November 2022","","",""
+"`3745 <https://wg21.link/LWG3745>`__","``std::atomic_wait`` and its friends lack ``noexcept``", "November 2022","|Complete|","16.0",""
 "`3746 <https://wg21.link/LWG3746>`__","``optional``'s spaceship with ``U`` with a type derived from optional causes infinite constraint meta-recursion", "November 2022","","","|spaceship|"
 "`3747 <https://wg21.link/LWG3747>`__","``ranges::uninitialized_copy_n``, ``ranges::uninitialized_move_n``, and ``ranges::destroy_n`` should use ``std::move``", "November 2022","","","|ranges|"
 "`3750 <https://wg21.link/LWG3750>`__","Too many papers bump ``__cpp_lib_format``", "November 2022","","","|format|"
index 87631f3..4fc565c 100644 (file)
@@ -377,23 +377,23 @@ template<class T>
                               memory_order) noexcept;
 
 template<class T>
-  void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type);
+  void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type) noexcept;
 template<class T>
-  void atomic_wait(const atomic<T>*, atomic<T>::value_type);
+  void atomic_wait(const atomic<T>*, atomic<T>::value_type) noexcept;
 template<class T>
   void atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
-                            memory_order);
+                            memory_order) noexcept;
 template<class T>
   void atomic_wait_explicit(const atomic<T>*, atomic<T>::value_type,
-                            memory_order);
+                            memory_order) noexcept;
 template<class T>
-  void atomic_notify_one(volatile atomic<T>*);
+  void atomic_notify_one(volatile atomic<T>*) noexcept;
 template<class T>
-  void atomic_notify_one(atomic<T>*);
+  void atomic_notify_one(atomic<T>*) noexcept;
 template<class T>
-  void atomic_notify_all(volatile atomic<T>*);
+  void atomic_notify_all(volatile atomic<T>*) noexcept;
 template<class T>
-  void atomic_notify_all(atomic<T>*);
+  void atomic_notify_all(atomic<T>*) noexcept;
 
 // Atomics for standard typedef types
 
@@ -2099,7 +2099,7 @@ void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
     __o->notify_one();
 }
 
-// atomic_notify_one
+// atomic_notify_all
 
 template <class _Tp>
 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
index 58d9772..92908bd 100644 (file)
 
 // template<class T>
 //     void
-//     atomic_notify_all(volatile atomic<T>*);
+//     atomic_notify_all(volatile atomic<T>*) noexcept;
 //
 // template<class T>
 //     void
-//     atomic_notify_all(atomic<T>*);
+//     atomic_notify_all(atomic<T>*) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -39,6 +39,7 @@ struct TestFn {
 
     {
       A a(T(1));
+      static_assert(noexcept(std::atomic_notify_all(&a)), "");
       auto f = [&]() {
         assert(std::atomic_load(&a) == T(1));
         std::atomic_wait(&a, T(1));
@@ -55,6 +56,7 @@ struct TestFn {
     }
     {
       volatile A a(T(2));
+      static_assert(noexcept(std::atomic_notify_all(&a)), "");
       auto f = [&]() {
         assert(std::atomic_load(&a) == T(2));
         std::atomic_wait(&a, T(2));
index 2c18742..5f8afa8 100644 (file)
 
 // template<class T>
 //     void
-//     atomic_notify_one(volatile atomic<T>*);
+//     atomic_notify_one(volatile atomic<T>*) noexcept;
 //
 // template<class T>
 //     void
-//     atomic_notify_one(atomic<T>*);
+//     atomic_notify_one(atomic<T>*) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -39,6 +39,7 @@ struct TestFn {
 
     {
       A a(T(1));
+      static_assert(noexcept(std::atomic_notify_one(&a)), "");
       std::thread t = support::make_test_thread([&]() {
         std::atomic_store(&a, T(3));
         std::atomic_notify_one(&a);
@@ -49,6 +50,7 @@ struct TestFn {
     }
     {
       volatile A a(T(2));
+      static_assert(noexcept(std::atomic_notify_one(&a)), "");
       std::thread t = support::make_test_thread([&]() {
         std::atomic_store(&a, T(4));
         std::atomic_notify_one(&a);
index 1557f41..2d4890e 100644 (file)
 
 // template<class T>
 //     void
-//     atomic_wait(const volatile atomic<T>*, atomic<T>::value_type);
+//     atomic_wait(const volatile atomic<T>*, atomic<T>::value_type) noexcept;
 //
 // template<class T>
 //     void
-//     atomic_wait(const atomic<T>*, atomic<T>::value_type);
+//     atomic_wait(const atomic<T>*, atomic<T>::value_type) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -38,6 +38,7 @@ struct TestFn {
     typedef std::atomic<T> A;
     {
       A t(T(1));
+      static_assert(noexcept(std::atomic_wait(&t, T(0))), "");
       assert(std::atomic_load(&t) == T(1));
       std::atomic_wait(&t, T(0));
       std::thread t1 = support::make_test_thread([&]() {
@@ -50,6 +51,7 @@ struct TestFn {
     }
     {
       volatile A vt(T(2));
+      static_assert(noexcept(std::atomic_wait(&vt, T(0))), "");
       assert(std::atomic_load(&vt) == T(2));
       std::atomic_wait(&vt, T(1));
       std::thread t2 = support::make_test_thread([&]() {
index 9799c77..00d1ce0 100644 (file)
 // template<class T>
 //     void
 //     atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
-//                          memory_order);
+//                          memory_order) noexcept;
 //
 // template<class T>
 //     void
 //     atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
-//                          memory_order);
+//                          memory_order) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -40,6 +40,7 @@ struct TestFn {
     typedef std::atomic<T> A;
     {
       A t(T(1));
+      static_assert(noexcept(std::atomic_wait_explicit(&t, T(0), std::memory_order_seq_cst)), "");
       assert(std::atomic_load(&t) == T(1));
       std::atomic_wait_explicit(&t, T(0), std::memory_order_seq_cst);
       std::thread t1 = support::make_test_thread([&]() {
@@ -52,6 +53,7 @@ struct TestFn {
     }
     {
       volatile A vt(T(2));
+      static_assert(noexcept(std::atomic_wait_explicit(&vt, T(0), std::memory_order_seq_cst)), "");
       assert(std::atomic_load(&vt) == T(2));
       std::atomic_wait_explicit(&vt, T(1), std::memory_order_seq_cst);
       std::thread t2 = support::make_test_thread([&]() {