[libcxx-commits] [libcxx] a76e698 - [libc++] Update atomic synopsis and tests.

Mark de Wever via libcxx-commits libcxx-commits at lists.llvm.org
Tue Oct 12 08:28:12 PDT 2021


Author: Mark de Wever
Date: 2021-10-12T17:28:08+02:00
New Revision: a76e698787e768488f74bd6481467407cba27022

URL: https://github.com/llvm/llvm-project/commit/a76e698787e768488f74bd6481467407cba27022
DIFF: https://github.com/llvm/llvm-project/commit/a76e698787e768488f74bd6481467407cba27022.diff

LOG: [libc++] Update atomic synopsis and tests.

While looking at LWG-2988 and P0558 it seems the issues were already
implemented, but the synopsis wasn't updated. Some of the tests didn't
validate the `noexcept` status. A few tests were missing completely:
- `atomic_wait_explicit`
- `atomic_notify_one`
- `atomic_notify_all`

Mark P0558 as complete, didn't investigate which version of libc++ first
includes this. It seems the paper has been retroactively applied. I
couldn't find whether this is correct, but looking at cppreference it
seems intended.

Completes
- LWG-2988 Clause 32 cleanup missed one typename
- P0558 Resolving atomic<T> named base class inconsistencies

Reviewed By: #libc, ldionne

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

Added: 
    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_explicit.pass.cpp

Modified: 
    libcxx/docs/Status/Cxx17Papers.csv
    libcxx/docs/Status/Cxx20Issues.csv
    libcxx/include/atomic
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Status/Cxx17Papers.csv b/libcxx/docs/Status/Cxx17Papers.csv
index a015529feed06..642a374496da4 100644
--- a/libcxx/docs/Status/Cxx17Papers.csv
+++ b/libcxx/docs/Status/Cxx17Papers.csv
@@ -101,7 +101,7 @@
 "`P0518R1 <https://wg21.link/P0518R1>`__","LWG","Allowing copies as arguments to function objects given to parallel algorithms in response to CH11","Kona","",""
 "`P0523R1 <https://wg21.link/P0523R1>`__","LWG","Wording for CH 10: Complexity of parallel algorithms","Kona","",""
 "`P0548R1 <https://wg21.link/P0548R1>`__","LWG","common_type and duration","Kona","|Complete|","5.0"
-"`P0558R1 <https://wg21.link/P0558R1>`__","LWG","Resolving atomic<T> named base class inconsistencies","Kona","",""
+"`P0558R1 <https://wg21.link/P0558R1>`__","LWG","Resolving atomic<T> named base class inconsistencies","Kona","|Complete|",""
 "`P0574R1 <https://wg21.link/P0574R1>`__","LWG","Algorithm Complexity Constraints and Parallel Overloads","Kona","",""
 "`P0599R1 <https://wg21.link/P0599R1>`__","LWG","noexcept for hash functions","Kona","|Complete|","5.0"
 "`P0604R0 <https://wg21.link/P0604R0>`__","LWG","Resolving GB 55, US 84, US 85, US 86","Kona","|Complete|",""

diff  --git a/libcxx/docs/Status/Cxx20Issues.csv b/libcxx/docs/Status/Cxx20Issues.csv
index deae7d59e30a4..f835afdf268ed 100644
--- a/libcxx/docs/Status/Cxx20Issues.csv
+++ b/libcxx/docs/Status/Cxx20Issues.csv
@@ -34,7 +34,7 @@
 "`2980 <https://wg21.link/LWG2980>`__","Cannot compare_exchange empty pointers","Albuquerque","",""
 "`2981 <https://wg21.link/LWG2981>`__","Remove redundant deduction guides from standard library","Albuquerque","",""
 "`2982 <https://wg21.link/LWG2982>`__","Making size_type consistent in associative container deduction guides","Albuquerque","",""
-"`2988 <https://wg21.link/LWG2988>`__","Clause 32 cleanup missed one typename","Albuquerque","",""
+"`2988 <https://wg21.link/LWG2988>`__","Clause 32 cleanup missed one typename","Albuquerque","|Complete|","13.0"
 "`2993 <https://wg21.link/LWG2993>`__","reference_wrapper<T> conversion from T&&","Albuquerque","|Complete|","13.0"
 "`2998 <https://wg21.link/LWG2998>`__","Requirements on function objects passed to {``forward_``,}list-specific algorithms","Albuquerque","|Nothing To Do|",""
 "`3001 <https://wg21.link/LWG3001>`__","weak_ptr::element_type needs remove_extent_t","Albuquerque","",""

diff  --git a/libcxx/include/atomic b/libcxx/include/atomic
index a10e596d49816..2e2ee63b676d0 100644
--- a/libcxx/include/atomic
+++ b/libcxx/include/atomic
@@ -263,196 +263,137 @@ struct atomic<T*>
 };
 
 
-template <class T>
-  bool atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
-
-template <class T>
-  bool atomic_is_lock_free(const atomic<T>* obj) noexcept;
-
-template <class T>
-  void atomic_store(volatile atomic<T>* obj, T desr) noexcept;
-
-template <class T>
-  void atomic_store(atomic<T>* obj, T desr) noexcept;
-
-template <class T>
-  void atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
-
-template <class T>
-  void atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
-
-template <class T>
-  T atomic_load(const volatile atomic<T>* obj) noexcept;
-
-template <class T>
-  T atomic_load(const atomic<T>* obj) noexcept;
-
-template <class T>
-  T atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
-
-template <class T>
-  T atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
-
-template <class T>
-  T atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
-
-template <class T>
-  T atomic_exchange(atomic<T>* obj, T desr) noexcept;
-
-template <class T>
-  T atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
-
-template <class T>
-  T atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
-
-template <class T>
-  bool atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
-
-template <class T>
-  bool atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
-
-template <class T>
-  bool atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
-
-template <class T>
-  bool atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
-
-template <class T>
-  bool atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
-                                             T desr,
-                                             memory_order s, memory_order f) noexcept;
-
-template <class T>
-  bool atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
-                                             memory_order s, memory_order f) noexcept;
-
-template <class T>
-  bool atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
-                                               T* expc, T desr,
-                                               memory_order s, memory_order f) noexcept;
-
-template <class T>
-  bool atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
-                                               T desr,
-                                               memory_order s, memory_order f) noexcept;
-
-template <class T>
-  void atomic_wait(const volatile atomic<T>* obj, T old) noexcept;
-
-template <class T>
-  void atomic_wait(const atomic<T>* obj, T old) noexcept;
-
-template <class T>
-  void atomic_wait_explicit(const volatile atomic<T>* obj, T old, memory_order m) noexcept;
-
-template <class T>
-  void atomic_wait_explicit(const atomic<T>* obj, T old, memory_order m) noexcept;
-
-template <class T>
-  void atomic_one(volatile atomic<T>* obj) noexcept;
-
-template <class T>
-  void atomic_one(atomic<T>* obj) noexcept;
-
-template <class T>
-  void atomic_all(volatile atomic<T>* obj) noexcept;
-
-template <class T>
-  void atomic_all(atomic<T>* obj) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
-                              memory_order m) noexcept;
-template <class Integral>
-  Integral atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
-                              memory_order m) noexcept;
-template <class Integral>
-  Integral atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
-                                     memory_order m) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
-                                     memory_order m) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
-                                     memory_order m) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
-                                     memory_order m) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
-                             memory_order m) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
-                             memory_order m) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
-                                     memory_order m) noexcept;
-
-template <class Integral>
-  Integral atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
-                                     memory_order m) noexcept;
-
-template <class T>
-  T* atomic_fetch_add(volatile atomic<T*>* obj, ptr
diff _t op) noexcept;
-
-template <class T>
-  T* atomic_fetch_add(atomic<T*>* obj, ptr
diff _t op) noexcept;
-
-template <class T>
-  T* atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptr
diff _t op,
-                               memory_order m) noexcept;
-
-template <class T>
-  T* atomic_fetch_add_explicit(atomic<T*>* obj, ptr
diff _t op, memory_order m) noexcept;
-
-template <class T>
-  T* atomic_fetch_sub(volatile atomic<T*>* obj, ptr
diff _t op) noexcept;
-
-template <class T>
-  T* atomic_fetch_sub(atomic<T*>* obj, ptr
diff _t op) noexcept;
-
-template <class T>
-  T* atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptr
diff _t op,
-                               memory_order m) noexcept;
-
-template <class T>
-  T* atomic_fetch_sub_explicit(atomic<T*>* obj, ptr
diff _t op, memory_order m) noexcept;
+// [atomics.nonmembers], non-member functions
+template<class T>
+  bool atomic_is_lock_free(const volatile atomic<T>*) noexcept;
+template<class T>
+  bool atomic_is_lock_free(const atomic<T>*) noexcept;
+template<class T>
+  void atomic_store(volatile atomic<T>*, atomic<T>::value_type) noexcept;
+template<class T>
+  void atomic_store(atomic<T>*, atomic<T>::value_type) noexcept;
+template<class T>
+  void atomic_store_explicit(volatile atomic<T>*, atomic<T>::value_type,
+                             memory_order) noexcept;
+template<class T>
+  void atomic_store_explicit(atomic<T>*, atomic<T>::value_type,
+                             memory_order) noexcept;
+template<class T>
+  T atomic_load(const volatile atomic<T>*) noexcept;
+template<class T>
+  T atomic_load(const atomic<T>*) noexcept;
+template<class T>
+  T atomic_load_explicit(const volatile atomic<T>*, memory_order) noexcept;
+template<class T>
+  T atomic_load_explicit(const atomic<T>*, memory_order) noexcept;
+template<class T>
+  T atomic_exchange(volatile atomic<T>*, atomic<T>::value_type) noexcept;
+template<class T>
+  T atomic_exchange(atomic<T>*, atomic<T>::value_type) noexcept;
+template<class T>
+  T atomic_exchange_explicit(volatile atomic<T>*, atomic<T>::value_type,
+                             memory_order) noexcept;
+template<class T>
+  T atomic_exchange_explicit(atomic<T>*, atomic<T>::value_type,
+                             memory_order) noexcept;
+template<class T>
+  bool atomic_compare_exchange_weak(volatile atomic<T>*, atomic<T>::value_type*,
+                                    atomic<T>::value_type) noexcept;
+template<class T>
+  bool atomic_compare_exchange_weak(atomic<T>*, atomic<T>::value_type*,
+                                    atomic<T>::value_type) noexcept;
+template<class T>
+  bool atomic_compare_exchange_strong(volatile atomic<T>*, atomic<T>::value_type*,
+                                      atomic<T>::value_type) noexcept;
+template<class T>
+  bool atomic_compare_exchange_strong(atomic<T>*, atomic<T>::value_type*,
+                                      atomic<T>::value_type) noexcept;
+template<class T>
+  bool atomic_compare_exchange_weak_explicit(volatile atomic<T>*, atomic<T>::value_type*,
+                                             atomic<T>::value_type,
+                                             memory_order, memory_order) noexcept;
+template<class T>
+  bool atomic_compare_exchange_weak_explicit(atomic<T>*, atomic<T>::value_type*,
+                                             atomic<T>::value_type,
+                                             memory_order, memory_order) noexcept;
+template<class T>
+  bool atomic_compare_exchange_strong_explicit(volatile atomic<T>*, atomic<T>::value_type*,
+                                               atomic<T>::value_type,
+                                               memory_order, memory_order) noexcept;
+template<class T>
+  bool atomic_compare_exchange_strong_explicit(atomic<T>*, atomic<T>::value_type*,
+                                               atomic<T>::value_type,
+                                               memory_order, memory_order) noexcept;
+
+template<class T>
+  T atomic_fetch_add(volatile atomic<T>*, atomic<T>::
diff erence_type) noexcept;
+template<class T>
+  T atomic_fetch_add(atomic<T>*, atomic<T>::
diff erence_type) noexcept;
+template<class T>
+  T atomic_fetch_add_explicit(volatile atomic<T>*, atomic<T>::
diff erence_type,
+                              memory_order) noexcept;
+template<class T>
+  T atomic_fetch_add_explicit(atomic<T>*, atomic<T>::
diff erence_type,
+                              memory_order) noexcept;
+template<class T>
+  T atomic_fetch_sub(volatile atomic<T>*, atomic<T>::
diff erence_type) noexcept;
+template<class T>
+  T atomic_fetch_sub(atomic<T>*, atomic<T>::
diff erence_type) noexcept;
+template<class T>
+  T atomic_fetch_sub_explicit(volatile atomic<T>*, atomic<T>::
diff erence_type,
+                              memory_order) noexcept;
+template<class T>
+  T atomic_fetch_sub_explicit(atomic<T>*, atomic<T>::
diff erence_type,
+                              memory_order) noexcept;
+template<class T>
+  T atomic_fetch_and(volatile atomic<T>*, atomic<T>::value_type) noexcept;
+template<class T>
+  T atomic_fetch_and(atomic<T>*, atomic<T>::value_type) noexcept;
+template<class T>
+  T atomic_fetch_and_explicit(volatile atomic<T>*, atomic<T>::value_type,
+                              memory_order) noexcept;
+template<class T>
+  T atomic_fetch_and_explicit(atomic<T>*, atomic<T>::value_type,
+                              memory_order) noexcept;
+template<class T>
+  T atomic_fetch_or(volatile atomic<T>*, atomic<T>::value_type) noexcept;
+template<class T>
+  T atomic_fetch_or(atomic<T>*, atomic<T>::value_type) noexcept;
+template<class T>
+  T atomic_fetch_or_explicit(volatile atomic<T>*, atomic<T>::value_type,
+                             memory_order) noexcept;
+template<class T>
+  T atomic_fetch_or_explicit(atomic<T>*, atomic<T>::value_type,
+                             memory_order) noexcept;
+template<class T>
+  T atomic_fetch_xor(volatile atomic<T>*, atomic<T>::value_type) noexcept;
+template<class T>
+  T atomic_fetch_xor(atomic<T>*, atomic<T>::value_type) noexcept;
+template<class T>
+  T atomic_fetch_xor_explicit(volatile atomic<T>*, atomic<T>::value_type,
+                              memory_order) noexcept;
+template<class T>
+  T atomic_fetch_xor_explicit(atomic<T>*, atomic<T>::value_type,
+                              memory_order) noexcept;
+
+template<class T>
+  void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type);
+template<class T>
+  void atomic_wait(const atomic<T>*, atomic<T>::value_type);
+template<class T>
+  void atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
+                            memory_order);
+template<class T>
+  void atomic_wait_explicit(const atomic<T>*, atomic<T>::value_type,
+                            memory_order);
+template<class T>
+  void atomic_notify_one(volatile atomic<T>*);
+template<class T>
+  void atomic_notify_one(atomic<T>*);
+template<class T>
+  void atomic_notify_all(volatile atomic<T>*);
+template<class T>
+  void atomic_notify_all(atomic<T>*);
 
 // Atomics for standard typedef types
 
@@ -564,10 +505,10 @@ void atomic_signal_fence(memory_order m) noexcept;
 // deprecated
 
 template <class T>
-  void atomic_init(volatile atomic<T>* obj, typename atomic<T>::value_type desr) noexcept;
+  void atomic_init(volatile atomic<T>* obj, atomic<T>::value_type desr) noexcept;
 
 template <class T>
-  void atomic_init(atomic<T>* obj, typename atomic<T>::value_type desr) noexcept;
+  void atomic_init(atomic<T>* obj, atomic<T>::value_type desr) noexcept;
 
 #define ATOMIC_VAR_INIT(value) see below
 

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp
index 1bb1c915ca514..539b4c654bdf3 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong.pass.cpp
@@ -8,17 +8,20 @@
 //
 // UNSUPPORTED: libcpp-has-no-threads
 // XFAIL: !non-lockfree-atomics
-//  ... assertion fails line 34
 
 // <atomic>
 
 // template <class T>
 //     bool
-//     atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr);
+//     atomic_compare_exchange_strong(volatile atomic<T>*,
+//                                    atomic<T>::value_type*,
+//                                    atomic<T>::value_type) noexcept;
 //
 // template <class T>
 //     bool
-//     atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr);
+//     atomic_compare_exchange_strong(atomic<T>*,
+//                                    atomic<T>::value_type*,
+//                                    atomic<T>::value_type) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -40,6 +43,8 @@ struct TestFn {
         assert(std::atomic_compare_exchange_strong(&a, &t, T(3)) == false);
         assert(a == T(2));
         assert(t == T(2));
+
+        ASSERT_NOEXCEPT(std::atomic_compare_exchange_strong(&a, &t, T(3)));
     }
     {
         typedef std::atomic<T> A;
@@ -51,6 +56,8 @@ struct TestFn {
         assert(std::atomic_compare_exchange_strong(&a, &t, T(3)) == false);
         assert(a == T(2));
         assert(t == T(2));
+
+        ASSERT_NOEXCEPT(std::atomic_compare_exchange_strong(&a, &t, T(3)));
     }
   }
 };

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp
index db3bad9172b26..38562598b8712 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_strong_explicit.pass.cpp
@@ -8,20 +8,22 @@
 //
 // UNSUPPORTED: libcpp-has-no-threads
 // XFAIL: !non-lockfree-atomics
-//  ... assertion fails line 38
 
 // <atomic>
 
 // template <class T>
 //     bool
-//     atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj, T* expc,
-//                                           T desr,
-//                                           memory_order s, memory_order f);
+//     atomic_compare_exchange_strong_explicit(volatile atomic<T>*,
+//                                             atomic<T>::value_type*,
+//                                             atomic<T>::value_type,
+//                                             memory_order, memory_order) noexcept;
 //
 // template <class T>
 //     bool
-//     atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc, T desr,
-//                                           memory_order s, memory_order f);
+//     atomic_compare_exchange_strong_explicit(atomic<T>*,
+//                                             atomic<T>::value_type*,
+//                                             atomic<T>::value_type,
+//                                             memory_order, memory_order) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -45,6 +47,9 @@ struct TestFn {
                std::memory_order_seq_cst, std::memory_order_seq_cst) == false);
         assert(a == T(2));
         assert(t == T(2));
+
+        ASSERT_NOEXCEPT(std::atomic_compare_exchange_strong_explicit(&a, &t, T(3), std::memory_order_seq_cst,
+                                                                     std::memory_order_seq_cst));
     }
     {
         typedef std::atomic<T> A;
@@ -58,6 +63,9 @@ struct TestFn {
                std::memory_order_seq_cst, std::memory_order_seq_cst) == false);
         assert(a == T(2));
         assert(t == T(2));
+
+        ASSERT_NOEXCEPT(std::atomic_compare_exchange_strong_explicit(&a, &t, T(3), std::memory_order_seq_cst,
+                                                                     std::memory_order_seq_cst));
     }
   }
 };

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp
index 0e4c5502cd900..cb1ab33619d4f 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak.pass.cpp
@@ -8,17 +8,20 @@
 //
 // UNSUPPORTED: libcpp-has-no-threads
 // XFAIL: !non-lockfree-atomics
-//  ... assertion fails line 34
 
 // <atomic>
 
 // template <class T>
 //     bool
-//     atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr);
+//     atomic_compare_exchange_weak(volatile atomic<T>*,
+//                                  atomic<T>::value_type*,
+//                                  atomic<T>::value_type) noexcept;
 //
 // template <class T>
 //     bool
-//     atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr);
+//     atomic_compare_exchange_weak(atomic<T>*,
+//                                  atomic<T>::value_type*,
+//                                  atomic<T>::value_type) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -41,6 +44,8 @@ struct TestFn {
         assert(std::atomic_compare_exchange_weak(&a, &t, T(3)) == false);
         assert(a == T(2));
         assert(t == T(2));
+
+        ASSERT_NOEXCEPT(std::atomic_compare_exchange_weak(&a, &t, T(3)));
     }
     {
         typedef std::atomic<T> A;
@@ -52,6 +57,8 @@ struct TestFn {
         assert(std::atomic_compare_exchange_weak(&a, &t, T(3)) == false);
         assert(a == T(2));
         assert(t == T(2));
+
+        ASSERT_NOEXCEPT(std::atomic_compare_exchange_weak(&a, &t, T(3)));
     }
   }
 };

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp
index ab0e50a7e19eb..265edbd281177 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_compare_exchange_weak_explicit.pass.cpp
@@ -8,20 +8,22 @@
 //
 // UNSUPPORTED: libcpp-has-no-threads
 // XFAIL: !non-lockfree-atomics
-//  ... assertion fails line 38
 
 // <atomic>
 
 // template <class T>
 //     bool
-//     atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
-//                                           T desr,
-//                                           memory_order s, memory_order f);
+//     atomic_compare_exchange_weak_explicit(volatile atomic<T>*,
+//                                           atomic<T>::value_type*,
+//                                           atomic<T>::value_type,
+//                                           memory_order, memory_order) noexcept;
 //
 // template <class T>
 //     bool
-//     atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
-//                                           memory_order s, memory_order f);
+//     atomic_compare_exchange_weak_explicit(atomic<T>*,
+//                                           atomic<T>::value_type*,
+//                                           atomic<T>::value_type,
+//                                           memory_order, memory_order) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -47,6 +49,9 @@ struct TestFn {
                std::memory_order_seq_cst, std::memory_order_seq_cst) == false);
         assert(a == T(2));
         assert(t == T(2));
+
+        ASSERT_NOEXCEPT(std::atomic_compare_exchange_weak_explicit(&a, &t, T(3), std::memory_order_seq_cst,
+                                                                   std::memory_order_seq_cst));
     }
     {
         typedef std::atomic<T> A;
@@ -60,6 +65,9 @@ struct TestFn {
                std::memory_order_seq_cst, std::memory_order_seq_cst) == false);
         assert(a == T(2));
         assert(t == T(2));
+
+        ASSERT_NOEXCEPT(std::atomic_compare_exchange_weak_explicit(&a, &t, T(3), std::memory_order_seq_cst,
+                                                                   std::memory_order_seq_cst));
     }
   }
 };

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp
index afad574ecc610..eb02d0aa1f54f 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange.pass.cpp
@@ -8,17 +8,16 @@
 //
 // UNSUPPORTED: libcpp-has-no-threads
 // XFAIL: !non-lockfree-atomics
-//  ... fails assertion line 31
 
 // <atomic>
 
 // template <class T>
 //     T
-//     atomic_exchange(volatile atomic<T>* obj, T desr);
+//     atomic_exchange(volatile atomic<T>*, atomic<T>::value_type) noexcept;
 //
 // template <class T>
 //     T
-//     atomic_exchange(atomic<T>* obj, T desr);
+//     atomic_exchange(atomic<T>*, atomic<T>::value_type) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -37,6 +36,9 @@ struct TestFn {
     volatile A vt(T(3));
     assert(std::atomic_exchange(&vt, T(4)) == T(3));
     assert(vt == T(4));
+
+    ASSERT_NOEXCEPT(std::atomic_exchange(&t, T(2)));
+    ASSERT_NOEXCEPT(std::atomic_exchange(&vt, T(4)));
   }
 };
 

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp
index b63a79482da81..e11dc0f65713a 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_exchange_explicit.pass.cpp
@@ -8,17 +8,18 @@
 //
 // UNSUPPORTED: libcpp-has-no-threads
 // XFAIL: !non-lockfree-atomics
-//  ... assertion fails line 32
 
 // <atomic>
 
 // template <class T>
 //     T
-//     atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m);
+//     atomic_exchange_explicit(volatile atomic<T>*, atomic<T>::value_type,
+//                              memory_order) noexcept;
 //
 // template <class T>
 //     T
-//     atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m);
+//     atomic_exchange_explicit(atomic<T>*, atomic<T>::value_type,
+//                              memory_order) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -39,6 +40,9 @@ struct TestFn {
     assert(std::atomic_exchange_explicit(&vt, T(4), std::memory_order_seq_cst)
            == T(3));
     assert(vt == T(4));
+
+    ASSERT_NOEXCEPT(std::atomic_exchange_explicit(&t, T(2), std::memory_order_seq_cst));
+    ASSERT_NOEXCEPT(std::atomic_exchange_explicit(&vt, T(4), std::memory_order_seq_cst));
   }
 };
 

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp
index 4863f2a4bcc96..0e4513c431798 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add.pass.cpp
@@ -10,21 +10,13 @@
 
 // <atomic>
 
-// template <class Integral>
-//     Integral
-//     atomic_fetch_add(volatile atomic<Integral>* obj, Integral op);
+// template<class T>
+//     T
+//     atomic_fetch_add(volatile atomic<T>* obj, atomic<T>::
diff erence_type) noexcept;
 //
-// template <class Integral>
-//     Integral
-//     atomic_fetch_add(atomic<Integral>* obj, Integral op);
-//
-// template <class T>
-//     T*
-//     atomic_fetch_add(volatile atomic<T>* obj, typename atomic<T>::
diff erence_type) noexcept;
-//
-// template <class T>
-//     T*
-//     atomic_fetch_add(atomic<T*>* obj, typename atomic<T>::
diff erence_type) noexcept;
+// template<class T>
+//     T
+//     atomic_fetch_add(atomic<T>* obj, atomic<T>::
diff erence_type) noexcept;
 
 #include <atomic>
 #include <type_traits>

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp
index 092666a171949..9a7f43a3bf0c6 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_add_explicit.pass.cpp
@@ -10,21 +10,15 @@
 
 // <atomic>
 
-// template <class Integral>
-//     Integral
-//     atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
-//                               memory_order m);
-// template <class Integral>
-//     Integral
-//     atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
-//                               memory_order m);
-// template <class T>
-//     T*
-//     atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptr
diff _t op,
-//                               memory_order m);
-// template <class T>
-//     T*
-//     atomic_fetch_add_explicit(atomic<T*>* obj, ptr
diff _t op, memory_order m);
+// template<class T>
+//     T
+//     atomic_fetch_add_explicit(volatile atomic<T>*, atomic<T>::
diff erence_type,
+//                               memory_order) noexcept;
+//
+// template<class T>
+//     T
+//     atomic_fetch_add_explicit(atomic<T>*, atomic<T>::
diff erence_type,
+//                               memory_order) noexcept;
 
 #include <atomic>
 #include <type_traits>

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp
index 6ea213285c509..6b5f72a23f531 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and.pass.cpp
@@ -10,13 +10,13 @@
 
 // <atomic>
 
-// template <class Integral>
-//     Integral
-//     atomic_fetch_and(volatile atomic<Integral>* obj, Integral op);
+// template<class T>
+//     T
+//     atomic_fetch_and(volatile atomic<T>*, atomic<T>::value_type) noexcept;
 //
-// template <class Integral>
-//     Integral
-//     atomic_fetch_and(atomic<Integral>* obj, Integral op);
+// template<class T>
+//     T
+//     atomic_fetch_and(atomic<T>*, atomic<T>::value_type) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -33,12 +33,16 @@ struct TestFn {
         A t(T(1));
         assert(std::atomic_fetch_and(&t, T(2)) == T(1));
         assert(t == T(0));
+
+        ASSERT_NOEXCEPT(std::atomic_fetch_and(&t, T(2)));
     }
     {
         typedef std::atomic<T> A;
         volatile A t(T(3));
         assert(std::atomic_fetch_and(&t, T(2)) == T(3));
         assert(t == T(2));
+
+        ASSERT_NOEXCEPT(std::atomic_fetch_and(&t, T(2)));
     }
   }
 };

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp
index 361afd5c18249..7b35f1cdf1e03 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_and_explicit.pass.cpp
@@ -10,13 +10,15 @@
 
 // <atomic>
 
-// template <class Integral>
-//     Integral
-//     atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op);
+// template<class T>
+//     T
+//     atomic_fetch_and_explicit(volatile atomic<T>*, atomic<T>::value_type,
+//                               memory_order) noexcept;
 //
-// template <class Integral>
-//     Integral
-//     atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op);
+// template<class T>
+//     T
+//     atomic_fetch_and_explicit(atomic<T>*, atomic<T>::value_type,
+//                               memory_order) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -34,6 +36,8 @@ struct TestFn {
         assert(std::atomic_fetch_and_explicit(&t, T(2),
                std::memory_order_seq_cst) == T(1));
         assert(t == T(0));
+
+        ASSERT_NOEXCEPT(std::atomic_fetch_and_explicit(&t, T(2), std::memory_order_seq_cst));
     }
     {
         typedef std::atomic<T> A;
@@ -41,6 +45,8 @@ struct TestFn {
         assert(std::atomic_fetch_and_explicit(&t, T(2),
                std::memory_order_seq_cst) == T(3));
         assert(t == T(2));
+
+        ASSERT_NOEXCEPT(std::atomic_fetch_and_explicit(&t, T(2), std::memory_order_seq_cst));
     }
   }
 };

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp
index 78bf4e0a3ef34..d74e0363dde70 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or.pass.cpp
@@ -10,13 +10,13 @@
 
 // <atomic>
 
-// template <class Integral>
-//     Integral
-//     atomic_fetch_or(volatile atomic<Integral>* obj, Integral op);
+// template<class T>
+//     T
+//     atomic_fetch_or(volatile atomic<T>*, atomic<T>::value_type) noexcept;
 //
-// template <class Integral>
-//     Integral
-//     atomic_fetch_or(atomic<Integral>* obj, Integral op);
+// template<class T>
+//     T
+//     atomic_fetch_or(atomic<T>*, atomic<T>::value_type) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -33,12 +33,16 @@ struct TestFn {
         A t(T(1));
         assert(std::atomic_fetch_or(&t, T(2)) == T(1));
         assert(t == T(3));
+
+        ASSERT_NOEXCEPT(std::atomic_fetch_or(&t, T(2)));
     }
     {
         typedef std::atomic<T> A;
         volatile A t(T(3));
         assert(std::atomic_fetch_or(&t, T(2)) == T(3));
         assert(t == T(3));
+
+        ASSERT_NOEXCEPT(std::atomic_fetch_or(&t, T(2)));
     }
   }
 };

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp
index 4effcb5b0cacd..02948a5301605 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_or_explicit.pass.cpp
@@ -10,13 +10,15 @@
 
 // <atomic>
 
-// template <class Integral>
-//     Integral
-//     atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op);
+// template<class T>
+//     T
+//     atomic_fetch_or_explicit(volatile atomic<T>*, atomic<T>::value_type,
+//                              memory_order) noexcept;
 //
-// template <class Integral>
-//     Integral
-//     atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op);
+// template<class T>
+//     T
+//     atomic_fetch_or_explicit(atomic<T>*, atomic<T>::value_type,
+//                              memory_order) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -34,6 +36,8 @@ struct TestFn {
         assert(std::atomic_fetch_or_explicit(&t, T(2),
                std::memory_order_seq_cst) == T(1));
         assert(t == T(3));
+
+        ASSERT_NOEXCEPT(std::atomic_fetch_or_explicit(&t, T(2), std::memory_order_seq_cst));
     }
     {
         typedef std::atomic<T> A;
@@ -41,6 +45,8 @@ struct TestFn {
         assert(std::atomic_fetch_or_explicit(&t, T(2),
                std::memory_order_seq_cst) == T(3));
         assert(t == T(3));
+
+        ASSERT_NOEXCEPT(std::atomic_fetch_or_explicit(&t, T(2), std::memory_order_seq_cst));
     }
   }
 };

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp
index deba7816e5b41..58d7b8a1bc8d0 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub.pass.cpp
@@ -10,21 +10,13 @@
 
 // <atomic>
 
-// template <class Integral>
-//     Integral
-//     atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op);
+// template<class T>
+//     T
+//     atomic_fetch_sub(volatile atomic<T>*, atomic<T>::
diff erence_type) noexcept;
 //
-// template <class Integral>
-//     Integral
-//     atomic_fetch_sub(atomic<Integral>* obj, Integral op);
-//
-// template <class T>
-//     T*
-//     atomic_fetch_sub(volatile atomic<T*>* obj, ptr
diff _t op);
-//
-// template <class T>
-//     T*
-//     atomic_fetch_sub(atomic<T*>* obj, ptr
diff _t op);
+// template<class T>
+//     T
+//     atomic_fetch_sub(atomic<T>*, atomic<T>::
diff erence_type) noexcept;
 
 #include <atomic>
 #include <type_traits>

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp
index 919c389b2d074..2dd4bc1df7158 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_sub_explicit.pass.cpp
@@ -10,22 +10,15 @@
 
 // <atomic>
 
-// template <class Integral>
-//     Integral
-//     atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
-//                               memory_order m);
-// template <class Integral>
-//     Integral
-//     atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
-//                               memory_order m);
+// template<class T>
+//     T
+//     atomic_fetch_sub_explicit(volatile atomic<T>*, atomic<T>::
diff erence_type,
+//                               memory_order) noexcept;
 //
-// template <class T>
-//     T*
-//     atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptr
diff _t op,
-//                               memory_order m);
-// template <class T>
-//     T*
-//     atomic_fetch_sub_explicit(atomic<T*>* obj, ptr
diff _t op, memory_order m);
+// template<class T>
+//     T
+//     atomic_fetch_sub_explicit(atomic<T>*, atomic<T>::
diff erence_type,
+//                               memory_order) noexcept;
 
 #include <atomic>
 #include <type_traits>

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp
index 874eabf2e1ee8..ae8494176f134 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor.pass.cpp
@@ -10,13 +10,13 @@
 
 // <atomic>
 
-// template <class Integral>
-//     Integral
-//     atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op);
+// template<class T>
+//     T
+//     atomic_fetch_xor(volatile atomic<T>*, atomic<T>::value_type) noexcept;
 //
-// template <class Integral>
-//     Integral
-//     atomic_fetch_xor(atomic<Integral>* obj, Integral op);
+// template<class T>
+//     T
+//     atomic_fetch_xor(atomic<T>*, atomic<T>::value_type) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -33,12 +33,16 @@ struct TestFn {
         A t(T(1));
         assert(std::atomic_fetch_xor(&t, T(2)) == T(1));
         assert(t == T(3));
+
+        ASSERT_NOEXCEPT(std::atomic_fetch_xor(&t, T(2)));
     }
     {
         typedef std::atomic<T> A;
         volatile A t(T(3));
         assert(std::atomic_fetch_xor(&t, T(2)) == T(3));
         assert(t == T(1));
+
+        ASSERT_NOEXCEPT(std::atomic_fetch_xor(&t, T(2)));
     }
   }
 };

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp
index f8f3e6ddb3d6f..3765dded6d6b6 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_fetch_xor_explicit.pass.cpp
@@ -10,13 +10,15 @@
 
 // <atomic>
 
-// template <class Integral>
-//     Integral
-//     atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op);
+// template<class T>
+//     T
+//     atomic_fetch_xor_explicit(volatile atomic<T>*, atomic<T>::value_type,
+//                               memory_order) noexcept;
 //
-// template <class Integral>
-//     Integral
-//     atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op);
+// template<class T>
+//     T
+//     atomic_fetch_xor_explicit(atomic<T>*, atomic<T>::value_type,
+//                               memory_order) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -34,6 +36,8 @@ struct TestFn {
         assert(std::atomic_fetch_xor_explicit(&t, T(2),
                std::memory_order_seq_cst) == T(1));
         assert(t == T(3));
+
+        ASSERT_NOEXCEPT(std::atomic_fetch_xor_explicit(&t, T(2), std::memory_order_seq_cst));
     }
     {
         typedef std::atomic<T> A;
@@ -41,6 +45,8 @@ struct TestFn {
         assert(std::atomic_fetch_xor_explicit(&t, T(2),
                std::memory_order_seq_cst) == T(3));
         assert(t == T(1));
+
+        ASSERT_NOEXCEPT(std::atomic_fetch_xor_explicit(&t, T(2), std::memory_order_seq_cst));
     }
   }
 };

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp
index 1de165d537ccd..da05491c858a0 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_init.pass.cpp
@@ -8,18 +8,17 @@
 //
 // UNSUPPORTED: libcpp-has-no-threads
 // XFAIL: !non-lockfree-atomics
-//  ... assertion fails line 36
 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
 
 // <atomic>
 
 // template <class T>
 //     void
-//     atomic_init(volatile atomic<T>* obj, T desr);
+//     atomic_init(volatile atomic<T>* obj, atomic<T>::value_type desr) noexcept;
 //
 // template <class T>
 //     void
-//     atomic_init(atomic<T>* obj, T desr);
+//     atomic_init(atomic<T>* obj, atomic<T>::value_type desr) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -38,6 +37,9 @@ struct TestFn {
     volatile A vt;
     std::atomic_init(&vt, T(2));
     assert(vt == T(2));
+
+    ASSERT_NOEXCEPT(std::atomic_init(&t, T(1)));
+    ASSERT_NOEXCEPT(std::atomic_init(&vt, T(2)));
   }
 };
 

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
index 25d1411834577..c3c4cc6d41739 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_is_lock_free.pass.cpp
@@ -12,10 +12,10 @@
 // <atomic>
 
 // template <class T>
-// bool atomic_is_lock_free(const volatile atomic<T>* obj);
+// bool atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
 //
 // template <class T>
-// bool atomic_is_lock_free(const atomic<T>* obj);
+// bool atomic_is_lock_free(const atomic<T>* obj) noexcept;
 
 #include <atomic>
 #include <cassert>
@@ -33,6 +33,9 @@ struct TestFn {
     volatile A va(t);
     bool b2 = std::atomic_is_lock_free(static_cast<const volatile A*>(&va));
     assert(b1 == b2);
+
+    ASSERT_NOEXCEPT(std::atomic_is_lock_free(static_cast<const A*>(&a)));
+    ASSERT_NOEXCEPT(std::atomic_is_lock_free(static_cast<const volatile A*>(&va)));
   }
 };
 

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp
index d9e672e1a9d20..408e45821ca5d 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load.pass.cpp
@@ -8,17 +8,16 @@
 //
 // UNSUPPORTED: libcpp-has-no-threads
 // XFAIL: !non-lockfree-atomics
-//  ... assertion fails line 35
 
 // <atomic>
 
 // template <class T>
 //     T
-//     atomic_load(const volatile atomic<T>* obj);
+//     atomic_load(const volatile atomic<T>*) noexcept;
 //
 // template <class T>
 //     T
-//     atomic_load(const atomic<T>* obj);
+//     atomic_load(const atomic<T>*) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -35,6 +34,9 @@ struct TestFn {
     assert(std::atomic_load(&t) == T(1));
     volatile A vt(T(2));
     assert(std::atomic_load(&vt) == T(2));
+
+    ASSERT_NOEXCEPT(std::atomic_load(&t));
+    ASSERT_NOEXCEPT(std::atomic_load(&vt));
   }
 };
 

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp
index 61a7929881fc3..e14791300ca43 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_load_explicit.pass.cpp
@@ -8,17 +8,16 @@
 //
 // UNSUPPORTED: libcpp-has-no-threads
 // XFAIL: !non-lockfree-atomics
-//  ... assertion fails line 31
 
 // <atomic>
 
 // template <class T>
 //     T
-//     atomic_load_explicit(const volatile atomic<T>* obj, memory_order m);
+//     atomic_load_explicit(const volatile atomic<T>*, memory_order) noexcept;
 //
 // template <class T>
 //     T
-//     atomic_load_explicit(const atomic<T>* obj, memory_order m);
+//     atomic_load_explicit(const atomic<T>*, memory_order) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -35,6 +34,9 @@ struct TestFn {
     assert(std::atomic_load_explicit(&t, std::memory_order_seq_cst) == T(1));
     volatile A vt(T(2));
     assert(std::atomic_load_explicit(&vt, std::memory_order_seq_cst) == T(2));
+
+    ASSERT_NOEXCEPT(std::atomic_load_explicit(&t, std::memory_order_seq_cst));
+    ASSERT_NOEXCEPT(std::atomic_load_explicit(&vt, std::memory_order_seq_cst));
   }
 };
 

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp
index 6077b0a853314..f1ad50c11c0fa 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store.pass.cpp
@@ -13,11 +13,11 @@
 
 // template <class T>
 //     void
-//     atomic_store(volatile atomic<T>* obj, T desr);
+//     atomic_store(volatile atomic<T>*, atomic<T>::value_type) noexcept;
 //
 // template <class T>
 //     void
-//     atomic_store(atomic<T>* obj, T desr);
+//     atomic_store(atomic<T>*, atomic<T>::value_type) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -36,6 +36,9 @@ struct TestFn {
     volatile A vt;
     std::atomic_store(&vt, T(2));
     assert(vt == T(2));
+
+    ASSERT_NOEXCEPT(std::atomic_store(&t, T(1)));
+    ASSERT_NOEXCEPT(std::atomic_store(&vt, T(2)));
   }
 };
 

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp
index 31342ac80e66a..cce59bef2b9b3 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_store_explicit.pass.cpp
@@ -13,11 +13,13 @@
 
 // template <class T>
 //     void
-//     atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m);
+//     atomic_store_explicit(volatile atomic<T>*, atomic<T>::value_type,
+//                           memory_order) noexcept;
 //
 // template <class T>
 //     void
-//     atomic_store_explicit(atomic<T>* obj, T desr, memory_order m);
+//     atomic_store_explicit(atomic<T>*, atomic<T>::value_type,
+//                           memory_order) noexcept;
 
 #include <atomic>
 #include <type_traits>
@@ -36,6 +38,9 @@ struct TestFn {
     volatile A vt;
     std::atomic_store_explicit(&vt, T(2), std::memory_order_seq_cst);
     assert(vt == T(2));
+
+    ASSERT_NOEXCEPT(std::atomic_store_explicit(&t, T(1), std::memory_order_seq_cst));
+    ASSERT_NOEXCEPT(std::atomic_store_explicit(&vt, T(2), std::memory_order_seq_cst));
   }
 };
 

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_notify_all.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_notify_all.pass.cpp
new file mode 100644
index 0000000000000..ad2bcebc88fd0
--- /dev/null
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_notify_all.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// XFAIL: c++03
+// XFAIL: !non-lockfree-atomics
+
+// This test requires the dylib support introduced in D68480, which shipped in
+// macOS 11.0.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+
+// <atomic>
+
+// template<class T>
+//     void
+//     atomic_notify_all(volatile atomic<T>*);
+//
+// template<class T>
+//     void
+//     atomic_notify_all(atomic<T>*);
+
+#include <atomic>
+#include <type_traits>
+#include <cassert>
+#include <thread>
+
+#include "make_test_thread.h"
+#include "test_macros.h"
+#include "atomic_helpers.h"
+
+template <class T>
+struct TestFn {
+  void operator()() const {
+    typedef std::atomic<T> A;
+
+    {
+      A a(T(1));
+      auto f = [&]() {
+        assert(std::atomic_load(&a) == T(1));
+        std::atomic_wait(&a, T(1));
+        assert(std::atomic_load(&a) == T(3));
+      };
+      std::thread t1 = support::make_test_thread(f);
+      std::thread t2 = support::make_test_thread(f);
+      std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+      std::atomic_store(&a, T(3));
+      std::atomic_notify_all(&a);
+      t1.join();
+      t2.join();
+    }
+    {
+      volatile A a(T(2));
+      auto f = [&]() {
+        assert(std::atomic_load(&a) == T(2));
+        std::atomic_wait(&a, T(2));
+        assert(std::atomic_load(&a) == T(4));
+      };
+      std::thread t1 = support::make_test_thread(f);
+      std::thread t2 = support::make_test_thread(f);
+      std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+      std::atomic_store(&a, T(4));
+      std::atomic_notify_all(&a);
+      t1.join();
+      t2.join();
+    }
+  }
+};
+
+int main(int, char**) {
+  TestEachAtomicType<TestFn>()();
+
+  return 0;
+}

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_notify_one.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_notify_one.pass.cpp
new file mode 100644
index 0000000000000..9b109939f78d2
--- /dev/null
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_notify_one.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// XFAIL: c++03
+// XFAIL: !non-lockfree-atomics
+
+// This test requires the dylib support introduced in D68480, which shipped in
+// macOS 11.0.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+
+// <atomic>
+
+// template<class T>
+//     void
+//     atomic_notify_one(volatile atomic<T>*);
+//
+// template<class T>
+//     void
+//     atomic_notify_one(atomic<T>*);
+
+#include <atomic>
+#include <type_traits>
+#include <cassert>
+#include <thread>
+
+#include "make_test_thread.h"
+#include "test_macros.h"
+#include "atomic_helpers.h"
+
+template <class T>
+struct TestFn {
+  void operator()() const {
+    typedef std::atomic<T> A;
+
+    {
+      A a(T(1));
+      std::thread t = support::make_test_thread([&]() {
+        std::atomic_store(&a, T(3));
+        std::atomic_notify_one(&a);
+      });
+      std::atomic_wait(&a, T(1));
+      assert(std::atomic_load(&a) == T(3));
+      t.join();
+    }
+    {
+      volatile A a(T(2));
+      std::thread t = support::make_test_thread([&]() {
+        std::atomic_store(&a, T(4));
+        std::atomic_notify_one(&a);
+      });
+      std::atomic_wait(&a, T(2));
+      assert(std::atomic_load(&a) == T(4));
+      t.join();
+    }
+  }
+};
+
+int main(int, char**) {
+  TestEachAtomicType<TestFn>()();
+
+  return 0;
+}

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait.pass.cpp
index 9e918e201dfda..6036b7c6ce0f6 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait.pass.cpp
@@ -16,6 +16,14 @@
 
 // <atomic>
 
+// template<class T>
+//     void
+//     atomic_wait(const volatile atomic<T>*, atomic<T>::value_type);
+//
+// template<class T>
+//     void
+//     atomic_wait(const atomic<T>*, atomic<T>::value_type);
+
 #include <atomic>
 #include <type_traits>
 #include <cassert>
@@ -29,32 +37,35 @@ template <class T>
 struct TestFn {
   void operator()() const {
     typedef std::atomic<T> A;
-
-    A t(T(1));
-    assert(std::atomic_load(&t) == T(1));
-    std::atomic_wait(&t, T(0));
-    std::thread t1 = support::make_test_thread([&](){
-      std::atomic_store(&t, T(3));
-      std::atomic_notify_one(&t);
-    });
-    std::atomic_wait(&t, T(1));
-    t1.join();
-
-    volatile A vt(T(2));
-    assert(std::atomic_load(&vt) == T(2));
-    std::atomic_wait(&vt, T(1));
-    std::thread t2 = support::make_test_thread([&](){
-      std::atomic_store(&vt, T(4));
-      std::atomic_notify_one(&vt);
-    });
-    std::atomic_wait(&vt, T(2));
-    t2.join();
+    {
+      A t(T(1));
+      assert(std::atomic_load(&t) == T(1));
+      std::atomic_wait(&t, T(0));
+      std::thread t1 = support::make_test_thread([&]() {
+        std::atomic_store(&t, T(3));
+        std::atomic_notify_one(&t);
+      });
+      std::atomic_wait(&t, T(1));
+      assert(std::atomic_load(&t) == T(3));
+      t1.join();
+    }
+    {
+      volatile A vt(T(2));
+      assert(std::atomic_load(&vt) == T(2));
+      std::atomic_wait(&vt, T(1));
+      std::thread t2 = support::make_test_thread([&]() {
+        std::atomic_store(&vt, T(4));
+        std::atomic_notify_one(&vt);
+      });
+      std::atomic_wait(&vt, T(2));
+      assert(std::atomic_load(&vt) == T(4));
+      t2.join();
+    }
   }
 };
 
-int main(int, char**)
-{
-    TestEachAtomicType<TestFn>()();
+int main(int, char**) {
+  TestEachAtomicType<TestFn>()();
 
   return 0;
 }

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait_explicit.pass.cpp
new file mode 100644
index 0000000000000..d88692fd22587
--- /dev/null
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait_explicit.pass.cpp
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// XFAIL: c++03
+// XFAIL: !non-lockfree-atomics
+
+// This test requires the dylib support introduced in D68480, which shipped in
+// macOS 11.0.
+// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14|15}}
+
+// <atomic>
+
+// template<class T>
+//     void
+//     atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
+//                          memory_order);
+//
+// template<class T>
+//     void
+//     atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
+//                          memory_order);
+
+#include <atomic>
+#include <type_traits>
+#include <cassert>
+#include <thread>
+
+#include "make_test_thread.h"
+#include "test_macros.h"
+#include "atomic_helpers.h"
+
+template <class T>
+struct TestFn {
+  void operator()() const {
+    typedef std::atomic<T> A;
+    {
+      A t(T(1));
+      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([&]() {
+        std::atomic_store(&t, T(3));
+        std::atomic_notify_one(&t);
+      });
+      std::atomic_wait_explicit(&t, T(1), std::memory_order_seq_cst);
+      assert(std::atomic_load(&t) == T(3));
+      t1.join();
+    }
+    {
+      volatile A vt(T(2));
+      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([&]() {
+        std::atomic_store(&vt, T(4));
+        std::atomic_notify_one(&vt);
+      });
+      std::atomic_wait_explicit(&vt, T(2), std::memory_order_seq_cst);
+      assert(std::atomic_load(&vt) == T(4));
+      t2.join();
+    }
+  }
+};
+
+int main(int, char**) {
+  TestEachAtomicType<TestFn>()();
+
+  return 0;
+}


        


More information about the libcxx-commits mailing list