diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv index c6225127a74b9..4aa796a7b0147 100644 --- a/libcxx/docs/Status/Cxx2cIssues.csv +++ b/libcxx/docs/Status/Cxx2cIssues.csv @@ -108,7 +108,7 @@ "`LWG4154 `__","The Mandates for ``std::packaged_task``'s constructor from a callable entity should consider decaying","2024-11 (Wrocław)","","","" "`LWG4157 `__","The resolution of LWG3465 was damaged by P2167R3","2024-11 (Wrocław)","|Complete|","20","" "`LWG4164 `__","Missing guarantees for ``forward_list`` modifiers","2024-11 (Wrocław)","|Complete|","21","" -"`LWG4169 `__","``std::atomic``'s default constructor should be constrained","2024-11 (Wrocław)","","","" +"`LWG4169 `__","``std::atomic``'s default constructor should be constrained","2024-11 (Wrocław)","|Complete|","22","" "`LWG4170 `__","``contiguous_iterator`` should require ``to_address(I{})``","2024-11 (Wrocław)","","","" "","","","","","" "`LWG3578 `__","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 eead49dde6192..5d30536ed4e3e 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> @@ -242,7 +243,9 @@ struct atomic : public __atomic_base::type 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 -#include - -#include "test_macros.h" - -template -constexpr bool test() { - [[maybe_unused]] constexpr T a; - static_assert(std::is_nothrow_constructible_v); - ASSERT_NOEXCEPT(T{}); - return true; -} - -struct throwing { - throwing() {} -}; - -struct trivial { - int a; -}; - -void test() { - static_assert(test>()); - static_assert(test>()); - static_assert(test>()); - static_assert(test>()); - static_assert(test()); - - static_assert(!std::is_nothrow_constructible_v>); - ASSERT_NOT_NOEXCEPT(std::atomic{}); -} 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 +#include + +#include "test_macros.h" + +template +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::value, ""); + ASSERT_NOEXCEPT(T{}); +} + +struct throwing { + throwing() {} +}; + +struct trivial { + int a; +}; + +struct not_default_constructible { + explicit not_default_constructible(int) {} +}; + +void test() { + test >(); + test >(); + test >(); + test >(); + test(); + +#if TEST_STD_VER >= 20 + static_assert(!std::is_nothrow_constructible_v>); + ASSERT_NOT_NOEXCEPT(std::atomic{}); + + static_assert(!std::is_default_constructible_v>); +#else + static_assert(std::is_nothrow_constructible >::value, ""); + + ASSERT_NOEXCEPT(std::atomic{}); +# ifndef TEST_COMPILER_GCC + static_assert(std::is_default_constructible >::value, ""); +# endif +#endif +}