Skip to content

Commit ab95005

Browse files
[libc++] P3247R2: Deprecate is_trivial(_v) (#130573)
Requirements on character-like types are updated unconditionally, because `basic_string` does requires the default-constructibility. It might be possible to make `basic_string_view` support classes with non-public trivial default constructor, but this doesn't seem sensible. libcxxabi's `ItaniumDemangle.h` is also updated to avoid deprecated features.
1 parent 36cb81c commit ab95005

File tree

28 files changed

+201
-76
lines changed

28 files changed

+201
-76
lines changed

libcxx/docs/ReleaseNotes/21.rst

+3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Implemented Papers
4545
- P2562R1: ``constexpr`` Stable Sorting (`Github <https://github.com/llvm/llvm-project/issues/105360>`__)
4646
- P0472R3: Put std::monostate in <utility> (`Github <https://github.com/llvm/llvm-project/issues/127874>`__)
4747
- P1222R4: A Standard ``flat_set`` (`Github <https://github.com/llvm/llvm-project/issues/105193>`__)
48+
- P3247R2: Deprecate the notion of trivial types (`Github <https://github.com/llvm/llvm-project/issues/118387>`__)
4849

4950
Improvements and New Features
5051
-----------------------------
@@ -65,6 +66,8 @@ Deprecations and Removals
6566

6667
- ``std::is_pod`` and ``std::is_pod_v`` are deprecated in C++20 and later.
6768

69+
- ``std::is_trivial`` and ``std::is_trivial_v`` are deprecated in C++26 and later.
70+
6871
Upcoming Deprecations and Removals
6972
----------------------------------
7073

libcxx/docs/Status/Cxx2cPapers.csv

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
"`P1928R15 <https://wg21.link/P1928R15>`__","``std::simd`` — merge data-parallel types from the Parallelism TS 2","2024-11 (Wrocław)","","",""
9595
"`P3325R5 <https://wg21.link/P3325R5>`__","A Utility for Creating Execution Environments","2024-11 (Wrocław)","","",""
9696
"`P3068R6 <https://wg21.link/P3068R6>`__","Allowing exception throwing in constant-evaluation","2024-11 (Wrocław)","","",""
97-
"`P3247R2 <https://wg21.link/P3247R2>`__","Deprecate the notion of trivial types","2024-11 (Wrocław)","","",""
97+
"`P3247R2 <https://wg21.link/P3247R2>`__","Deprecate the notion of trivial types","2024-11 (Wrocław)","|Complete|","21",""
9898
"","","","","",""
9999
"`P3074R7 <https://wg21.link/P3074R7>`__","trivial unions (was ``std::uninitialized``)","2025-02 (Hagenberg)","","",""
100100
"`P1494R5 <https://wg21.link/P1494R5>`__","Partial program correctness","2025-02 (Hagenberg)","","",""

libcxx/include/__config

+2
Original file line numberDiff line numberDiff line change
@@ -742,8 +742,10 @@ typedef __char32_t char32_t;
742742

743743
# if _LIBCPP_STD_VER >= 26
744744
# define _LIBCPP_DEPRECATED_IN_CXX26 _LIBCPP_DEPRECATED
745+
# define _LIBCPP_DEPRECATED_IN_CXX26_(m) _LIBCPP_DEPRECATED_(m)
745746
# else
746747
# define _LIBCPP_DEPRECATED_IN_CXX26
748+
# define _LIBCPP_DEPRECATED_IN_CXX26_(m)
747749
# endif
748750

749751
# if _LIBCPP_HAS_CHAR8_T

libcxx/include/__iterator/aliasing_iterator.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
#include <__iterator/iterator_traits.h>
1515
#include <__memory/addressof.h>
1616
#include <__memory/pointer_traits.h>
17-
#include <__type_traits/is_trivial.h>
17+
#include <__type_traits/is_trivially_constructible.h>
18+
#include <__type_traits/is_trivially_copyable.h>
1819

1920
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
2021
# pragma GCC system_header
@@ -45,7 +46,8 @@ struct __aliasing_iterator_wrapper {
4546
using reference = value_type&;
4647
using pointer = value_type*;
4748

48-
static_assert(is_trivial<value_type>::value);
49+
static_assert(is_trivially_default_constructible<value_type>::value);
50+
static_assert(is_trivially_copyable<value_type>::value);
4951
static_assert(sizeof(__base_value_type) == sizeof(value_type));
5052

5153
_LIBCPP_HIDE_FROM_ABI __iterator() = default;

libcxx/include/__type_traits/is_char_like_type.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
#include <__config>
1313
#include <__type_traits/conjunction.h>
1414
#include <__type_traits/is_standard_layout.h>
15-
#include <__type_traits/is_trivial.h>
15+
#include <__type_traits/is_trivially_constructible.h>
16+
#include <__type_traits/is_trivially_copyable.h>
1617

1718
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
1819
# pragma GCC system_header
@@ -21,7 +22,8 @@
2122
_LIBCPP_BEGIN_NAMESPACE_STD
2223

2324
template <class _CharT>
24-
using _IsCharLikeType _LIBCPP_NODEBUG = _And<is_standard_layout<_CharT>, is_trivial<_CharT> >;
25+
using _IsCharLikeType _LIBCPP_NODEBUG =
26+
_And<is_standard_layout<_CharT>, is_trivially_default_constructible<_CharT>, is_trivially_copyable<_CharT> >;
2527

2628
_LIBCPP_END_NAMESPACE_STD
2729

libcxx/include/__type_traits/is_trivial.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@
1919
_LIBCPP_BEGIN_NAMESPACE_STD
2020

2121
template <class _Tp>
22-
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS is_trivial : public integral_constant<bool, __is_trivial(_Tp)> {
23-
};
22+
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX26_(
23+
"Consider using is_trivially_copyable<T>::value && is_trivially_default_constructible<T>::value instead.")
24+
_LIBCPP_NO_SPECIALIZATIONS is_trivial : public integral_constant<bool, __is_trivial(_Tp)> {};
2425

2526
#if _LIBCPP_STD_VER >= 17
2627
template <class _Tp>
28+
_LIBCPP_DEPRECATED_IN_CXX26_(
29+
"Consider using is_trivially_copyable_v<T> && is_trivially_default_constructible_v<T> instead.")
2730
_LIBCPP_NO_SPECIALIZATIONS inline constexpr bool is_trivial_v = __is_trivial(_Tp);
2831
#endif
2932

libcxx/include/string

+5-2
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,8 @@ basic_string<char32_t> operator""s( const char32_t *str, size_t len );
632632
# include <__type_traits/is_nothrow_constructible.h>
633633
# include <__type_traits/is_same.h>
634634
# include <__type_traits/is_standard_layout.h>
635-
# include <__type_traits/is_trivial.h>
635+
# include <__type_traits/is_trivially_constructible.h>
636+
# include <__type_traits/is_trivially_copyable.h>
636637
# include <__type_traits/is_trivially_relocatable.h>
637638
# include <__type_traits/remove_cvref.h>
638639
# include <__type_traits/void_t.h>
@@ -788,7 +789,9 @@ public:
788789

789790
static_assert(!is_array<value_type>::value, "Character type of basic_string must not be an array");
790791
static_assert(is_standard_layout<value_type>::value, "Character type of basic_string must be standard-layout");
791-
static_assert(is_trivial<value_type>::value, "Character type of basic_string must be trivial");
792+
static_assert(is_trivially_default_constructible<value_type>::value,
793+
"Character type of basic_string must be trivially default constructible");
794+
static_assert(is_trivially_copyable<value_type>::value, "Character type of basic_string must be trivially copyable");
792795
static_assert(is_same<_CharT, typename traits_type::char_type>::value,
793796
"traits_type::char_type must be the same type as CharT");
794797
static_assert(is_same<typename allocator_type::value_type, value_type>::value,

libcxx/include/string_view

+6-2
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,8 @@ namespace std {
235235
# include <__type_traits/is_convertible.h>
236236
# include <__type_traits/is_same.h>
237237
# include <__type_traits/is_standard_layout.h>
238-
# include <__type_traits/is_trivial.h>
238+
# include <__type_traits/is_trivially_constructible.h>
239+
# include <__type_traits/is_trivially_copyable.h>
239240
# include <__type_traits/remove_cvref.h>
240241
# include <__type_traits/remove_reference.h>
241242
# include <__type_traits/type_identity.h>
@@ -302,7 +303,10 @@ public:
302303

303304
static_assert(!is_array<value_type>::value, "Character type of basic_string_view must not be an array");
304305
static_assert(is_standard_layout<value_type>::value, "Character type of basic_string_view must be standard-layout");
305-
static_assert(is_trivial<value_type>::value, "Character type of basic_string_view must be trivial");
306+
static_assert(is_trivially_default_constructible<value_type>::value,
307+
"Character type of basic_string_view must be trivially default constructible");
308+
static_assert(is_trivially_copyable<value_type>::value,
309+
"Character type of basic_string_view must be trivially copyable");
306310
static_assert(is_same<_CharT, typename traits_type::char_type>::value,
307311
"traits_type::char_type must be the same type as CharT");
308312

libcxx/include/type_traits

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ namespace std
9393
template <class T> struct is_unbounded_array; // since C++20
9494
9595
// Member introspection:
96-
template <class T> struct is_trivial;
96+
template <class T> struct is_trivial; // deprecated in C++26
9797
template <class T> struct is_pod; // deprecated in C++20
9898
template <class T> struct is_trivially_copyable;
9999
template <class T> struct is_standard_layout;
@@ -323,7 +323,7 @@ namespace std
323323
template <class T> inline constexpr bool is_volatile_v
324324
= is_volatile<T>::value; // since C++17
325325
template <class T> inline constexpr bool is_trivial_v
326-
= is_trivial<T>::value; // since C++17
326+
= is_trivial<T>::value; // since C++17; deprecated in C++26
327327
template <class T> inline constexpr bool is_trivially_copyable_v
328328
= is_trivially_copyable<T>::value; // since C++17
329329
template <class T> inline constexpr bool is_standard_layout_v

libcxx/test/libcxx/memory/allocator_void.trivial.compile.pass.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ typedef std::allocator<void> A1;
2020
struct A2 : std::allocator<void> { };
2121

2222
static_assert(std::is_trivially_default_constructible<A1>::value, "");
23-
static_assert(std::is_trivial<A1>::value, "");
23+
static_assert(std::is_trivially_copyable<A1>::value, "");
2424

2525
static_assert(std::is_trivially_default_constructible<A2>::value, "");
26-
static_assert(std::is_trivial<A2>::value, "");
26+
static_assert(std::is_trivially_copyable<A2>::value, "");

libcxx/test/libcxx/utilities/memory/util.smartptr/util.smartptr.shared/libcxx.control_block_layout.pass.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ void test() {
123123

124124
// Make sure both types have the same triviality (that has ABI impact since
125125
// it determined how objects are passed). Both should be non-trivial.
126-
static_assert(std::is_trivial<New>::value == std::is_trivial<Old>::value, "");
126+
static_assert(std::is_trivially_copyable<New>::value == std::is_trivially_copyable<Old>::value, "");
127+
static_assert(
128+
std::is_trivially_default_constructible<New>::value == std::is_trivially_default_constructible<Old>::value, "");
127129
}
128130

129131
// Object types to store in the control block

libcxx/test/libcxx/utilities/utility/private_constructor_tag.compile.pass.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@
1818
#include <__utility/private_constructor_tag.h>
1919
#include <type_traits>
2020

21-
static_assert(std::is_trivial<std::__private_constructor_tag>::value, "");
21+
static_assert(std::is_trivially_copyable<std::__private_constructor_tag>::value, "");
22+
static_assert(std::is_trivially_default_constructible<std::__private_constructor_tag>::value, "");

libcxx/test/std/depr/depr.c.headers/stddef_h.compile.pass.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ static_assert((std::is_same<decltype(nullptr), nullptr_t>::value), "");
4343
static_assert(sizeof(nullptr_t) == sizeof(void*), "");
4444
#if TEST_STD_VER >= 11
4545
# if TEST_STD_VER >= 20
46-
// P0767
47-
static_assert(std::is_trivial<max_align_t>::value, "");
46+
// P0767R1 and P3247R2
47+
static_assert(std::is_trivially_copyable<max_align_t>::value, "");
48+
static_assert(std::is_trivially_default_constructible<max_align_t>::value, "");
4849
static_assert(std::is_standard_layout<max_align_t>::value, "");
4950
# else
5051
static_assert(std::is_pod<max_align_t>::value, "");

libcxx/test/std/language.support/support.types/byte.pass.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
// It is a distinct type for accessing the bits that ultimately make up object storage.
1717

1818
#if TEST_STD_VER > 17
19-
static_assert( std::is_trivial<std::byte>::value, "" ); // P0767
19+
static_assert(std::is_trivially_copyable<std::byte>::value, "");
20+
static_assert(std::is_trivially_default_constructible<std::byte>::value, "");
21+
static_assert(std::is_standard_layout<std::byte>::value, "");
2022
#else
2123
static_assert( std::is_pod<std::byte>::value, "" );
2224
#endif

libcxx/test/std/language.support/support.types/max_align_t.compile.pass.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616

1717
#include "test_macros.h"
1818

19-
static_assert(std::is_trivial<std::max_align_t>::value, "");
19+
static_assert(std::is_trivially_copyable<std::max_align_t>::value, "");
20+
static_assert(std::is_trivially_default_constructible<std::max_align_t>::value, "");
2021
static_assert(std::is_standard_layout<std::max_align_t>::value, "");
2122
#if TEST_STD_VER <= 17
2223
static_assert(std::is_pod<std::max_align_t>::value, "");

libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ template <class CPO, class... Args>
2323
constexpr bool test(CPO& o, Args&&...) {
2424
static_assert(std::is_const_v<CPO>);
2525
static_assert(std::is_class_v<CPO>);
26-
static_assert(std::is_trivial_v<CPO>);
26+
static_assert(std::is_trivially_copyable_v<CPO>);
27+
static_assert(std::is_trivially_default_constructible_v<CPO>);
2728

2829
auto p = o;
2930
using T = decltype(p);

libcxx/test/std/library/description/conventions/customization.point.object/niebloid.compile.pass.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ template <class CPO, class... Args>
3636
constexpr bool test(CPO& o, Args&&...) {
3737
static_assert(std::is_const_v<CPO>);
3838
static_assert(std::is_class_v<CPO>);
39-
static_assert(std::is_trivial_v<CPO>);
39+
static_assert(std::is_trivially_copyable_v<CPO>);
40+
static_assert(std::is_trivially_default_constructible_v<CPO>);
4041

4142
auto p = o;
4243
using T = decltype(p);

libcxx/test/std/ranges/range.req/range.view/view_base.compile.pass.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
#include <type_traits>
1717

1818
static_assert(std::is_empty_v<std::ranges::view_base>);
19-
static_assert(std::is_trivial_v<std::ranges::view_base>);
19+
static_assert(std::is_trivially_copyable_v<std::ranges::view_base>);
20+
static_assert(std::is_trivially_default_constructible_v<std::ranges::view_base>);
2021

2122
// Make sure we can inherit from it, as it's intended (that wouldn't be the
2223
// case if e.g. it was marked as final).

libcxx/test/std/strings/basic.string/char.bad.verify.cpp

+24-6
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,25 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
10+
911
// <string>
1012
// ... manipulating sequences of any non-array trivial standard-layout types.
1113

1214
#include <string>
15+
#include <type_traits>
1316
#include "test_traits.h"
1417

15-
struct NotTrivial {
16-
NotTrivial() : value(3) {}
18+
struct NotTriviallyCopyable {
19+
int value;
20+
NotTriviallyCopyable& operator=(const NotTriviallyCopyable& other) {
21+
value = other.value;
22+
return *this;
23+
}
24+
};
25+
26+
struct NotTriviallyDefaultConstructible {
27+
NotTriviallyDefaultConstructible() : value(3) {}
1728
int value;
1829
};
1930

@@ -37,10 +48,17 @@ void f() {
3748
}
3849

3950
{
40-
// not trivial
41-
static_assert(!std::is_trivial<NotTrivial>::value, "");
42-
std::basic_string<NotTrivial, test_traits<NotTrivial> > s;
43-
// expected-error-re@*:* {{static assertion failed{{.*}}Character type of basic_string must be trivial}}
51+
// not trivially copyable
52+
static_assert(!std::is_trivially_copyable<NotTriviallyCopyable>::value, "");
53+
std::basic_string<NotTriviallyCopyable, test_traits<NotTriviallyCopyable> > s;
54+
// expected-error-re@*:* {{static assertion failed{{.*}}Character type of basic_string must be trivially copyable}}
55+
}
56+
57+
{
58+
// not trivially default constructible
59+
static_assert(!std::is_trivially_default_constructible<NotTriviallyDefaultConstructible>::value, "");
60+
std::basic_string<NotTriviallyDefaultConstructible, test_traits<NotTriviallyDefaultConstructible> > s;
61+
// expected-error-re@*:* {{static assertion failed{{.*}}Character type of basic_string must be trivially default constructible}}
4462
}
4563

4664
{

libcxx/test/std/strings/string.view/char.bad.verify.cpp

+22-6
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,19 @@
1414
// ... manipulating sequences of any non-array trivial standard-layout types.
1515

1616
#include <string>
17+
#include <type_traits>
1718
#include "../basic.string/test_traits.h"
1819

19-
struct NotTrivial {
20-
NotTrivial() : value(3) {}
20+
struct NotTriviallyCopyable {
21+
int value;
22+
NotTriviallyCopyable& operator=(const NotTriviallyCopyable& other) {
23+
value = other.value;
24+
return *this;
25+
}
26+
};
27+
28+
struct NotTriviallyDefaultConstructible {
29+
NotTriviallyDefaultConstructible() : value(3) {}
2130
int value;
2231
};
2332

@@ -41,10 +50,17 @@ int main(int, char**) {
4150
}
4251

4352
{
44-
// not trivial
45-
static_assert(!std::is_trivial<NotTrivial>::value, "");
46-
std::basic_string_view<NotTrivial, test_traits<NotTrivial> > sv;
47-
// expected-error-re@string_view:* {{static assertion failed{{.*}}Character type of basic_string_view must be trivial}}
53+
// not trivially copyable
54+
static_assert(!std::is_trivially_copyable<NotTriviallyCopyable>::value, "");
55+
std::basic_string_view<NotTriviallyCopyable, test_traits<NotTriviallyCopyable> > s;
56+
// expected-error-re@*:* {{static assertion failed{{.*}}Character type of basic_string_view must be trivially copyable}}
57+
}
58+
59+
{
60+
// not trivially default constructible
61+
static_assert(!std::is_trivially_default_constructible<NotTriviallyDefaultConstructible>::value, "");
62+
std::basic_string_view<NotTriviallyDefaultConstructible, test_traits<NotTriviallyDefaultConstructible> > sv;
63+
// expected-error-re@string_view:* {{static assertion failed{{.*}}Character type of basic_string_view must be trivially default constructible}}
4864
}
4965

5066
{

libcxx/test/std/time/time.zone/time.zone.zonedtraits/types.compile.pass.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,14 @@
2424

2525
// This test test whether non-specialized versions exhibit the expected
2626
// behavior. (Note these specializations are not really useful.)
27-
static_assert(std::is_trivial_v<std::chrono::zoned_traits<int>>);
28-
static_assert(std::is_trivial_v<std::chrono::zoned_traits<float>>);
29-
static_assert(std::is_trivial_v<std::chrono::zoned_traits<void*>>);
27+
static_assert(std::is_trivially_copyable_v<std::chrono::zoned_traits<int>>);
28+
static_assert(std::is_trivially_copyable_v<std::chrono::zoned_traits<float>>);
29+
static_assert(std::is_trivially_copyable_v<std::chrono::zoned_traits<void*>>);
30+
static_assert(std::is_trivially_default_constructible_v<std::chrono::zoned_traits<int>>);
31+
static_assert(std::is_trivially_default_constructible_v<std::chrono::zoned_traits<float>>);
32+
static_assert(std::is_trivially_default_constructible_v<std::chrono::zoned_traits<void*>>);
3033

3134
struct foo {};
3235
static_assert(std::is_empty_v<std::chrono::zoned_traits<foo>>);
33-
static_assert(std::is_trivial_v<std::chrono::zoned_traits<foo>>);
36+
static_assert(std::is_trivially_copyable_v<std::chrono::zoned_traits<foo>>);
37+
static_assert(std::is_trivially_default_constructible_v<std::chrono::zoned_traits<foo>>);

0 commit comments

Comments
 (0)