[libcxx-commits] [libcxx] [libc++] LWG4169: `std::atomic<T>`'s default constructor should be constrained (PR #131950)
A. Jiang via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Mar 19 05:19:32 PDT 2025
https://github.com/frederick-vs-ja updated https://github.com/llvm/llvm-project/pull/131950
>From 10d5433c33dfd6b6937fc0e783352fc807127fa8 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Wed, 19 Mar 2025 11:58:53 +0800
Subject: [PATCH] [libc++] LWG4169 constrain `std::atomic<T>`'s default
constructor
Drive-by: Rename `constexpr_noexcept.compile.pass.cpp` to
`default_constructor.compile.pass.cpp` as test coverage is added to it,
and run it in all modes.
---
libcxx/docs/Status/Cxx2cIssues.csv | 2 +-
libcxx/include/__atomic/atomic.h | 5 +-
.../constexpr_noexcept.compile.pass.cpp | 41 ------------
.../default_constructor.compile.pass.cpp | 64 +++++++++++++++++++
4 files changed, 69 insertions(+), 43 deletions(-)
delete mode 100644 libcxx/test/std/atomics/atomics.types.generic/constexpr_noexcept.compile.pass.cpp
create mode 100644 libcxx/test/std/atomics/atomics.types.generic/default_constructor.compile.pass.cpp
diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index 9bf31c417f3c9..66d286fd6c38c 100644
--- a/libcxx/docs/Status/Cxx2cIssues.csv
+++ b/libcxx/docs/Status/Cxx2cIssues.csv
@@ -108,7 +108,7 @@
"`LWG4154 <https://wg21.link/LWG4154>`__","The Mandates for ``std::packaged_task``'s constructor from a callable entity should consider decaying","2024-11 (Wrocław)","","",""
"`LWG4157 <https://wg21.link/LWG4157>`__","The resolution of LWG3465 was damaged by P2167R3","2024-11 (Wrocław)","","20",""
"`LWG4164 <https://wg21.link/LWG4164>`__","Missing guarantees for ``forward_list`` modifiers","2024-11 (Wrocław)","","",""
-"`LWG4169 <https://wg21.link/LWG4169>`__","``std::atomic<T>``'s default constructor should be constrained","2024-11 (Wrocław)","","",""
+"`LWG4169 <https://wg21.link/LWG4169>`__","``std::atomic<T>``'s default constructor should be constrained","2024-11 (Wrocław)","|Complete|","21",""
"`LWG4170 <https://wg21.link/LWG4170>`__","``contiguous_iterator`` should require ``to_address(I{})``","2024-11 (Wrocław)","","",""
"","","","","",""
"`LWG3578 <https://wg21.link/3578>`__","Iterator SCARYness in the context of associative container merging","2025-02 (Hagenberg)","","",""
diff --git a/libcxx/include/__atomic/atomic.h b/libcxx/include/__atomic/atomic.h
index c65f9afe4f390..e96ce2aab8587 100644
--- a/libcxx/include/__atomic/atomic.h
+++ b/libcxx/include/__atomic/atomic.h
@@ -18,6 +18,7 @@
#include <__cstddef/ptrdiff_t.h>
#include <__memory/addressof.h>
#include <__type_traits/enable_if.h>
+#include <__type_traits/is_constructible.h>
#include <__type_traits/is_floating_point.h>
#include <__type_traits/is_function.h>
#include <__type_traits/is_integral.h>
@@ -235,7 +236,9 @@ struct atomic : public __atomic_base<_Tp> {
using __base _LIBCPP_NODEBUG = __atomic_base<_Tp>;
#if _LIBCPP_STD_VER >= 20
- _LIBCPP_HIDE_FROM_ABI atomic() = default;
+ _LIBCPP_HIDE_FROM_ABI atomic()
+ requires is_default_constructible_v<_Tp>
+ = default;
#else
_LIBCPP_HIDE_FROM_ABI atomic() _NOEXCEPT = default;
#endif
diff --git a/libcxx/test/std/atomics/atomics.types.generic/constexpr_noexcept.compile.pass.cpp b/libcxx/test/std/atomics/atomics.types.generic/constexpr_noexcept.compile.pass.cpp
deleted file mode 100644
index fca52a998eace..0000000000000
--- a/libcxx/test/std/atomics/atomics.types.generic/constexpr_noexcept.compile.pass.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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: c++03, c++11, c++14, c++17
-
-#include <atomic>
-#include <type_traits>
-
-#include "test_macros.h"
-
-template <typename T>
-constexpr bool test() {
- [[maybe_unused]] constexpr T a;
- static_assert(std::is_nothrow_constructible_v<T>);
- ASSERT_NOEXCEPT(T{});
- return true;
-}
-
-struct throwing {
- throwing() {}
-};
-
-struct trivial {
- int a;
-};
-
-void test() {
- static_assert(test<std::atomic<bool>>());
- static_assert(test<std::atomic<int>>());
- static_assert(test<std::atomic<int*>>());
- static_assert(test<std::atomic<trivial>>());
- static_assert(test<std::atomic_flag>());
-
- static_assert(!std::is_nothrow_constructible_v<std::atomic<throwing>>);
- ASSERT_NOT_NOEXCEPT(std::atomic<throwing>{});
-}
diff --git a/libcxx/test/std/atomics/atomics.types.generic/default_constructor.compile.pass.cpp b/libcxx/test/std/atomics/atomics.types.generic/default_constructor.compile.pass.cpp
new file mode 100644
index 0000000000000..e1a3eb183bf27
--- /dev/null
+++ b/libcxx/test/std/atomics/atomics.types.generic/default_constructor.compile.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// Test the properties of std::atomic's default constructor.
+
+#include <atomic>
+#include <type_traits>
+
+#include "test_macros.h"
+
+template <typename T>
+void test() {
+#if TEST_STD_VER >= 11
+ constexpr T a{};
+ (void)a;
+# if TEST_STD_VER >= 20
+ [[maybe_unused]] constexpr T b;
+# endif
+#else
+ T a;
+ (void)a;
+#endif
+ static_assert(std::is_nothrow_constructible<T>::value, "");
+ ASSERT_NOEXCEPT(T{});
+}
+
+struct throwing {
+ throwing() {}
+};
+
+struct trivial {
+ int a;
+};
+
+struct not_default_constructible {
+ explicit not_default_constructible(int) {}
+};
+
+void test() {
+ test<std::atomic<bool> >();
+ test<std::atomic<int> >();
+ test<std::atomic<int*> >();
+ test<std::atomic<trivial> >();
+ test<std::atomic_flag>();
+
+#if TEST_STD_VER >= 20
+ static_assert(!std::is_nothrow_constructible_v<std::atomic<throwing>>);
+ ASSERT_NOT_NOEXCEPT(std::atomic<throwing>{});
+
+ static_assert(!std::is_default_constructible_v<std::atomic<not_default_constructible>>);
+#else
+ static_assert(std::is_nothrow_constructible<std::atomic<throwing> >::value, "");
+
+ ASSERT_NOEXCEPT(std::atomic<throwing>{});
+# ifndef TEST_COMPILER_GCC
+ static_assert(std::is_default_constructible<std::atomic<not_default_constructible> >::value, "");
+# endif
+#endif
+}
More information about the libcxx-commits
mailing list