[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
Tue Mar 18 22:41:36 PDT 2025


https://github.com/frederick-vs-ja updated https://github.com/llvm/llvm-project/pull/131950

>From 960c2407122a6c233d21fc73949cc9c3674f58bd 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