Skip to content

Commit 4624000

Browse files
[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.
1 parent e848959 commit 4624000

File tree

4 files changed

+69
-43
lines changed

4 files changed

+69
-43
lines changed

libcxx/docs/Status/Cxx2cIssues.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@
108108
"`LWG4154 <https://wg21.link/LWG4154>`__","The Mandates for ``std::packaged_task``'s constructor from a callable entity should consider decaying","2024-11 (Wrocław)","","",""
109109
"`LWG4157 <https://wg21.link/LWG4157>`__","The resolution of LWG3465 was damaged by P2167R3","2024-11 (Wrocław)","|Complete|","20",""
110110
"`LWG4164 <https://wg21.link/LWG4164>`__","Missing guarantees for ``forward_list`` modifiers","2024-11 (Wrocław)","|Complete|","21",""
111-
"`LWG4169 <https://wg21.link/LWG4169>`__","``std::atomic<T>``'s default constructor should be constrained","2024-11 (Wrocław)","","",""
111+
"`LWG4169 <https://wg21.link/LWG4169>`__","``std::atomic<T>``'s default constructor should be constrained","2024-11 (Wrocław)","|Complete|","22",""
112112
"`LWG4170 <https://wg21.link/LWG4170>`__","``contiguous_iterator`` should require ``to_address(I{})``","2024-11 (Wrocław)","","",""
113113
"","","","","",""
114114
"`LWG3578 <https://wg21.link/LWG3578>`__","Iterator SCARYness in the context of associative container merging","2025-02 (Hagenberg)","","",""

libcxx/include/__atomic/atomic.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <__cstddef/ptrdiff_t.h>
1919
#include <__memory/addressof.h>
2020
#include <__type_traits/enable_if.h>
21+
#include <__type_traits/is_constructible.h>
2122
#include <__type_traits/is_floating_point.h>
2223
#include <__type_traits/is_function.h>
2324
#include <__type_traits/is_integral.h>
@@ -242,7 +243,9 @@ struct atomic : public __atomic_base<typename __check_atomic_mandates<_Tp>::type
242243
using __base _LIBCPP_NODEBUG = __atomic_base<_Tp>;
243244

244245
#if _LIBCPP_STD_VER >= 20
245-
_LIBCPP_HIDE_FROM_ABI atomic() = default;
246+
_LIBCPP_HIDE_FROM_ABI atomic()
247+
requires is_default_constructible_v<_Tp>
248+
= default;
246249
#else
247250
_LIBCPP_HIDE_FROM_ABI atomic() _NOEXCEPT = default;
248251
#endif

libcxx/test/std/atomics/atomics.types.generic/constexpr_noexcept.compile.pass.cpp

Lines changed: 0 additions & 41 deletions
This file was deleted.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// Test the properties of std::atomic's default constructor.
10+
11+
#include <atomic>
12+
#include <type_traits>
13+
14+
#include "test_macros.h"
15+
16+
template <typename T>
17+
void test() {
18+
#if TEST_STD_VER >= 11
19+
constexpr T a{};
20+
(void)a;
21+
# if TEST_STD_VER >= 20
22+
[[maybe_unused]] constexpr T b;
23+
# endif
24+
#else
25+
T a;
26+
(void)a;
27+
#endif
28+
static_assert(std::is_nothrow_constructible<T>::value, "");
29+
ASSERT_NOEXCEPT(T{});
30+
}
31+
32+
struct throwing {
33+
throwing() {}
34+
};
35+
36+
struct trivial {
37+
int a;
38+
};
39+
40+
struct not_default_constructible {
41+
explicit not_default_constructible(int) {}
42+
};
43+
44+
void test() {
45+
test<std::atomic<bool> >();
46+
test<std::atomic<int> >();
47+
test<std::atomic<int*> >();
48+
test<std::atomic<trivial> >();
49+
test<std::atomic_flag>();
50+
51+
#if TEST_STD_VER >= 20
52+
static_assert(!std::is_nothrow_constructible_v<std::atomic<throwing>>);
53+
ASSERT_NOT_NOEXCEPT(std::atomic<throwing>{});
54+
55+
static_assert(!std::is_default_constructible_v<std::atomic<not_default_constructible>>);
56+
#else
57+
static_assert(std::is_nothrow_constructible<std::atomic<throwing> >::value, "");
58+
59+
ASSERT_NOEXCEPT(std::atomic<throwing>{});
60+
# ifndef TEST_COMPILER_GCC
61+
static_assert(std::is_default_constructible<std::atomic<not_default_constructible> >::value, "");
62+
# endif
63+
#endif
64+
}

0 commit comments

Comments
 (0)