Skip to content

Commit 83c1816

Browse files
committed
[libc++] LWG3745 noexcept for atomic_wait.
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
1 parent 28b52ab commit 83c1816

File tree

6 files changed

+26
-18
lines changed

6 files changed

+26
-18
lines changed

libcxx/docs/Status/Cxx2bIssues.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@
205205
"`3737 <https://wg21.link/LWG3737>`__","``take_view::sentinel`` should provide ``operator-``", "November 2022","","","|ranges|"
206206
"`3738 <https://wg21.link/LWG3738>`__","Missing preconditions for ``take_view`` constructor", "November 2022","","","|ranges|"
207207
"`3743 <https://wg21.link/LWG3743>`__","``ranges::to``'s reserve may be ill-formed", "November 2022","","","|ranges|"
208-
"`3745 <https://wg21.link/LWG3745>`__","``std::atomic_wait`` and its friends lack ``noexcept``", "November 2022","","",""
208+
"`3745 <https://wg21.link/LWG3745>`__","``std::atomic_wait`` and its friends lack ``noexcept``", "November 2022","|Complete|","16.0",""
209209
"`3746 <https://wg21.link/LWG3746>`__","``optional``'s spaceship with ``U`` with a type derived from optional causes infinite constraint meta-recursion", "November 2022","","","|spaceship|"
210210
"`3747 <https://wg21.link/LWG3747>`__","``ranges::uninitialized_copy_n``, ``ranges::uninitialized_move_n``, and ``ranges::destroy_n`` should use ``std::move``", "November 2022","","","|ranges|"
211211
"`3750 <https://wg21.link/LWG3750>`__","Too many papers bump ``__cpp_lib_format``", "November 2022","","","|format|"

libcxx/include/atomic

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -377,23 +377,23 @@ template<class T>
377377
memory_order) noexcept;
378378
379379
template<class T>
380-
void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type);
380+
void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type) noexcept;
381381
template<class T>
382-
void atomic_wait(const atomic<T>*, atomic<T>::value_type);
382+
void atomic_wait(const atomic<T>*, atomic<T>::value_type) noexcept;
383383
template<class T>
384384
void atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
385-
memory_order);
385+
memory_order) noexcept;
386386
template<class T>
387387
void atomic_wait_explicit(const atomic<T>*, atomic<T>::value_type,
388-
memory_order);
388+
memory_order) noexcept;
389389
template<class T>
390-
void atomic_notify_one(volatile atomic<T>*);
390+
void atomic_notify_one(volatile atomic<T>*) noexcept;
391391
template<class T>
392-
void atomic_notify_one(atomic<T>*);
392+
void atomic_notify_one(atomic<T>*) noexcept;
393393
template<class T>
394-
void atomic_notify_all(volatile atomic<T>*);
394+
void atomic_notify_all(volatile atomic<T>*) noexcept;
395395
template<class T>
396-
void atomic_notify_all(atomic<T>*);
396+
void atomic_notify_all(atomic<T>*) noexcept;
397397
398398
// Atomics for standard typedef types
399399
@@ -2099,7 +2099,7 @@ void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
20992099
__o->notify_one();
21002100
}
21012101

2102-
// atomic_notify_one
2102+
// atomic_notify_all
21032103

21042104
template <class _Tp>
21052105
_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY

libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_notify_all.pass.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717

1818
// template<class T>
1919
// void
20-
// atomic_notify_all(volatile atomic<T>*);
20+
// atomic_notify_all(volatile atomic<T>*) noexcept;
2121
//
2222
// template<class T>
2323
// void
24-
// atomic_notify_all(atomic<T>*);
24+
// atomic_notify_all(atomic<T>*) noexcept;
2525

2626
#include <atomic>
2727
#include <type_traits>
@@ -39,6 +39,7 @@ struct TestFn {
3939

4040
{
4141
A a(T(1));
42+
static_assert(noexcept(std::atomic_notify_all(&a)), "");
4243
auto f = [&]() {
4344
assert(std::atomic_load(&a) == T(1));
4445
std::atomic_wait(&a, T(1));
@@ -55,6 +56,7 @@ struct TestFn {
5556
}
5657
{
5758
volatile A a(T(2));
59+
static_assert(noexcept(std::atomic_notify_all(&a)), "");
5860
auto f = [&]() {
5961
assert(std::atomic_load(&a) == T(2));
6062
std::atomic_wait(&a, T(2));

libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_notify_one.pass.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717

1818
// template<class T>
1919
// void
20-
// atomic_notify_one(volatile atomic<T>*);
20+
// atomic_notify_one(volatile atomic<T>*) noexcept;
2121
//
2222
// template<class T>
2323
// void
24-
// atomic_notify_one(atomic<T>*);
24+
// atomic_notify_one(atomic<T>*) noexcept;
2525

2626
#include <atomic>
2727
#include <type_traits>
@@ -39,6 +39,7 @@ struct TestFn {
3939

4040
{
4141
A a(T(1));
42+
static_assert(noexcept(std::atomic_notify_one(&a)), "");
4243
std::thread t = support::make_test_thread([&]() {
4344
std::atomic_store(&a, T(3));
4445
std::atomic_notify_one(&a);
@@ -49,6 +50,7 @@ struct TestFn {
4950
}
5051
{
5152
volatile A a(T(2));
53+
static_assert(noexcept(std::atomic_notify_one(&a)), "");
5254
std::thread t = support::make_test_thread([&]() {
5355
std::atomic_store(&a, T(4));
5456
std::atomic_notify_one(&a);

libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait.pass.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717

1818
// template<class T>
1919
// void
20-
// atomic_wait(const volatile atomic<T>*, atomic<T>::value_type);
20+
// atomic_wait(const volatile atomic<T>*, atomic<T>::value_type) noexcept;
2121
//
2222
// template<class T>
2323
// void
24-
// atomic_wait(const atomic<T>*, atomic<T>::value_type);
24+
// atomic_wait(const atomic<T>*, atomic<T>::value_type) noexcept;
2525

2626
#include <atomic>
2727
#include <type_traits>
@@ -38,6 +38,7 @@ struct TestFn {
3838
typedef std::atomic<T> A;
3939
{
4040
A t(T(1));
41+
static_assert(noexcept(std::atomic_wait(&t, T(0))), "");
4142
assert(std::atomic_load(&t) == T(1));
4243
std::atomic_wait(&t, T(0));
4344
std::thread t1 = support::make_test_thread([&]() {
@@ -50,6 +51,7 @@ struct TestFn {
5051
}
5152
{
5253
volatile A vt(T(2));
54+
static_assert(noexcept(std::atomic_wait(&vt, T(0))), "");
5355
assert(std::atomic_load(&vt) == T(2));
5456
std::atomic_wait(&vt, T(1));
5557
std::thread t2 = support::make_test_thread([&]() {

libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait_explicit.pass.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
// template<class T>
1919
// void
2020
// atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
21-
// memory_order);
21+
// memory_order) noexcept;
2222
//
2323
// template<class T>
2424
// void
2525
// atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
26-
// memory_order);
26+
// memory_order) noexcept;
2727

2828
#include <atomic>
2929
#include <type_traits>
@@ -40,6 +40,7 @@ struct TestFn {
4040
typedef std::atomic<T> A;
4141
{
4242
A t(T(1));
43+
static_assert(noexcept(std::atomic_wait_explicit(&t, T(0), std::memory_order_seq_cst)), "");
4344
assert(std::atomic_load(&t) == T(1));
4445
std::atomic_wait_explicit(&t, T(0), std::memory_order_seq_cst);
4546
std::thread t1 = support::make_test_thread([&]() {
@@ -52,6 +53,7 @@ struct TestFn {
5253
}
5354
{
5455
volatile A vt(T(2));
56+
static_assert(noexcept(std::atomic_wait_explicit(&vt, T(0), std::memory_order_seq_cst)), "");
5557
assert(std::atomic_load(&vt) == T(2));
5658
std::atomic_wait_explicit(&vt, T(1), std::memory_order_seq_cst);
5759
std::thread t2 = support::make_test_thread([&]() {

0 commit comments

Comments
 (0)