Skip to content

Commit 9599e24

Browse files
authored
Merge branch 'llvm:main' into fix-spirv-triple
2 parents 5b5bd98 + 45d493b commit 9599e24

File tree

24 files changed

+791
-74
lines changed

24 files changed

+791
-74
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,7 @@ set(files
845845
__type_traits/is_reference.h
846846
__type_traits/is_reference_wrapper.h
847847
__type_traits/is_referenceable.h
848+
__type_traits/is_replaceable.h
848849
__type_traits/is_same.h
849850
__type_traits/is_scalar.h
850851
__type_traits/is_signed.h

libcxx/include/__exception/exception_ptr.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,10 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr {
6565
friend _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep) _NOEXCEPT;
6666

6767
public:
68-
// exception_ptr is basically a COW string.
68+
// exception_ptr is basically a COW string so it is trivially relocatable.
69+
// It is also replaceable because assignment has normal value semantics.
6970
using __trivially_relocatable _LIBCPP_NODEBUG = exception_ptr;
71+
using __replaceable _LIBCPP_NODEBUG = exception_ptr;
7072

7173
_LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {}
7274
_LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}

libcxx/include/__expected/expected.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <__type_traits/is_nothrow_assignable.h>
3131
#include <__type_traits/is_nothrow_constructible.h>
3232
#include <__type_traits/is_reference.h>
33+
#include <__type_traits/is_replaceable.h>
3334
#include <__type_traits/is_same.h>
3435
#include <__type_traits/is_swappable.h>
3536
#include <__type_traits/is_trivially_constructible.h>
@@ -471,6 +472,8 @@ class expected : private __expected_base<_Tp, _Err> {
471472
__conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value && __libcpp_is_trivially_relocatable<_Err>::value,
472473
expected,
473474
void>;
475+
using __replaceable _LIBCPP_NODEBUG =
476+
__conditional_t<__is_replaceable_v<_Tp> && __is_replaceable_v<_Err>, expected, void>;
474477

475478
template <class _Up>
476479
using rebind = expected<_Up, error_type>;

libcxx/include/__locale

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@ _LIBCPP_HIDE_FROM_ABI const _Facet& use_facet(const locale&);
5656

5757
class _LIBCPP_EXPORTED_FROM_ABI locale {
5858
public:
59-
// locale is essentially a shared_ptr that doesn't support weak_ptrs and never got a move constructor.
59+
// locale is essentially a shared_ptr that doesn't support weak_ptrs and never got a move constructor,
60+
// so it is trivially relocatable. Like shared_ptr, it is also replaceable.
6061
using __trivially_relocatable _LIBCPP_NODEBUG = locale;
62+
using __replaceable _LIBCPP_NODEBUG = locale;
6163

6264
// types:
6365
class _LIBCPP_EXPORTED_FROM_ABI facet;

libcxx/include/__memory/shared_ptr.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,10 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI shared_ptr {
316316
#endif
317317

318318
// A shared_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
319-
// any bookkeeping, so it's always trivially relocatable.
319+
// any bookkeeping, so it's always trivially relocatable. It is also replaceable because assignment just rebinds the
320+
// shared_ptr to manage a different object.
320321
using __trivially_relocatable _LIBCPP_NODEBUG = shared_ptr;
322+
using __replaceable _LIBCPP_NODEBUG = shared_ptr;
321323

322324
private:
323325
element_type* __ptr_;
@@ -1211,8 +1213,9 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI weak_ptr {
12111213
#endif
12121214

12131215
// A weak_ptr contains only two raw pointers which point to the heap and move constructing already doesn't require
1214-
// any bookkeeping, so it's always trivially relocatable.
1216+
// any bookkeeping, so it's always trivially relocatable. It's also replaceable for the same reason.
12151217
using __trivially_relocatable _LIBCPP_NODEBUG = weak_ptr;
1218+
using __replaceable _LIBCPP_NODEBUG = weak_ptr;
12161219

12171220
private:
12181221
element_type* __ptr_;

libcxx/include/__memory/unique_ptr.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <__type_traits/is_function.h>
4040
#include <__type_traits/is_pointer.h>
4141
#include <__type_traits/is_reference.h>
42+
#include <__type_traits/is_replaceable.h>
4243
#include <__type_traits/is_same.h>
4344
#include <__type_traits/is_swappable.h>
4445
#include <__type_traits/is_trivially_relocatable.h>
@@ -144,6 +145,8 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr {
144145
__libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value,
145146
unique_ptr,
146147
void>;
148+
using __replaceable _LIBCPP_NODEBUG =
149+
__conditional_t<__is_replaceable_v<pointer> && __is_replaceable_v<deleter_type>, unique_ptr, void>;
147150

148151
private:
149152
_LIBCPP_COMPRESSED_PAIR(pointer, __ptr_, deleter_type, __deleter_);
@@ -410,6 +413,8 @@ class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI unique_ptr<_Tp[], _Dp> {
410413
__libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<deleter_type>::value,
411414
unique_ptr,
412415
void>;
416+
using __replaceable _LIBCPP_NODEBUG =
417+
__conditional_t<__is_replaceable_v<pointer> && __is_replaceable_v<deleter_type>, unique_ptr, void>;
413418

414419
private:
415420
template <class _Up, class _OtherDeleter>

libcxx/include/__split_buffer

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <__type_traits/integral_constant.h>
2929
#include <__type_traits/is_nothrow_assignable.h>
3030
#include <__type_traits/is_nothrow_constructible.h>
31+
#include <__type_traits/is_replaceable.h>
3132
#include <__type_traits/is_swappable.h>
3233
#include <__type_traits/is_trivially_destructible.h>
3334
#include <__type_traits/is_trivially_relocatable.h>
@@ -72,6 +73,10 @@ public:
7273
__libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<allocator_type>::value,
7374
__split_buffer,
7475
void>;
76+
using __replaceable _LIBCPP_NODEBUG =
77+
__conditional_t<__is_replaceable_v<pointer> && __container_allocator_is_replaceable<__alloc_traits>::value,
78+
__split_buffer,
79+
void>;
7580

7681
pointer __first_;
7782
pointer __begin_;
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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+
#ifndef _LIBCPP___TYPE_TRAITS_IS_REPLACEABLE_H
10+
#define _LIBCPP___TYPE_TRAITS_IS_REPLACEABLE_H
11+
12+
#include <__config>
13+
#include <__type_traits/enable_if.h>
14+
#include <__type_traits/integral_constant.h>
15+
#include <__type_traits/is_same.h>
16+
#include <__type_traits/is_trivially_copyable.h>
17+
18+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19+
# pragma GCC system_header
20+
#endif
21+
22+
_LIBCPP_BEGIN_NAMESPACE_STD
23+
24+
// A type is replaceable if, with `x` and `y` being different objects, `x = std::move(y)` is equivalent to:
25+
//
26+
// std::destroy_at(&x)
27+
// std::construct_at(&x, std::move(y))
28+
//
29+
// This allows turning a move-assignment into a sequence of destroy + move-construct, which
30+
// is often more efficient. This is especially relevant when the move-construct is in fact
31+
// part of a trivial relocation from somewhere else, in which case there is a huge win.
32+
//
33+
// Note that this requires language support in order to be really effective, but we
34+
// currently emulate the base template with something very conservative.
35+
template <class _Tp, class = void>
36+
struct __is_replaceable : is_trivially_copyable<_Tp> {};
37+
38+
template <class _Tp>
39+
struct __is_replaceable<_Tp, __enable_if_t<is_same<_Tp, typename _Tp::__replaceable>::value> > : true_type {};
40+
41+
template <class _Tp>
42+
inline const bool __is_replaceable_v = __is_replaceable<_Tp>::value;
43+
44+
// Determines whether an allocator member of a container is replaceable.
45+
//
46+
// First, we require the allocator type to be considered replaceable. If not, then something fishy might be
47+
// happening. Assuming the allocator type is replaceable, we conclude replaceability of the allocator as a
48+
// member of the container if the allocator always compares equal (in which case propagation doesn't matter),
49+
// or if the allocator always propagates on assignment, which is required in order for move construction and
50+
// assignment to be equivalent.
51+
template <class _AllocatorTraits>
52+
struct __container_allocator_is_replaceable
53+
: integral_constant<bool,
54+
__is_replaceable_v<typename _AllocatorTraits::allocator_type> &&
55+
(_AllocatorTraits::is_always_equal::value ||
56+
(_AllocatorTraits::propagate_on_container_move_assignment::value &&
57+
_AllocatorTraits::propagate_on_container_copy_assignment::value))> {};
58+
59+
_LIBCPP_END_NAMESPACE_STD
60+
61+
#endif // _LIBCPP___TYPE_TRAITS_IS_REPLACEABLE_H

libcxx/include/__utility/pair.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include <__type_traits/is_implicitly_default_constructible.h>
3333
#include <__type_traits/is_nothrow_assignable.h>
3434
#include <__type_traits/is_nothrow_constructible.h>
35+
#include <__type_traits/is_replaceable.h>
36+
#include <__type_traits/is_same.h>
3537
#include <__type_traits/is_swappable.h>
3638
#include <__type_traits/is_trivially_relocatable.h>
3739
#include <__type_traits/nat.h>
@@ -100,6 +102,7 @@ struct pair
100102
__conditional_t<__libcpp_is_trivially_relocatable<_T1>::value && __libcpp_is_trivially_relocatable<_T2>::value,
101103
pair,
102104
void>;
105+
using __replaceable _LIBCPP_NODEBUG = __conditional_t<__is_replaceable_v<_T1> && __is_replaceable_v<_T2>, pair, void>;
103106

104107
_LIBCPP_HIDE_FROM_ABI pair(pair const&) = default;
105108
_LIBCPP_HIDE_FROM_ABI pair(pair&&) = default;

libcxx/include/__vector/vector.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include <__type_traits/is_nothrow_assignable.h>
5656
#include <__type_traits/is_nothrow_constructible.h>
5757
#include <__type_traits/is_pointer.h>
58+
#include <__type_traits/is_replaceable.h>
5859
#include <__type_traits/is_same.h>
5960
#include <__type_traits/is_trivially_relocatable.h>
6061
#include <__type_traits/type_identity.h>
@@ -120,6 +121,10 @@ class vector {
120121
__libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<allocator_type>::value,
121122
vector,
122123
void>;
124+
using __replaceable _LIBCPP_NODEBUG =
125+
__conditional_t<__is_replaceable_v<pointer> && __container_allocator_is_replaceable<__alloc_traits>::value,
126+
vector,
127+
void>;
123128

124129
static_assert(__check_valid_allocator<allocator_type>::value, "");
125130
static_assert(is_same<typename allocator_type::value_type, value_type>::value,

libcxx/include/array

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce
134134
# include <__type_traits/is_const.h>
135135
# include <__type_traits/is_constructible.h>
136136
# include <__type_traits/is_nothrow_constructible.h>
137+
# include <__type_traits/is_replaceable.h>
137138
# include <__type_traits/is_same.h>
138139
# include <__type_traits/is_swappable.h>
139140
# include <__type_traits/is_trivially_relocatable.h>
@@ -175,6 +176,7 @@ template <class _Tp, size_t _Size>
175176
struct array {
176177
using __trivially_relocatable _LIBCPP_NODEBUG =
177178
__conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, array, void>;
179+
using __replaceable _LIBCPP_NODEBUG = __conditional_t<__is_replaceable_v<_Tp>, array, void>;
178180

179181
// types:
180182
using __self _LIBCPP_NODEBUG = array;

libcxx/include/deque

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ template <class T, class Allocator, class Predicate>
230230
# include <__type_traits/is_convertible.h>
231231
# include <__type_traits/is_nothrow_assignable.h>
232232
# include <__type_traits/is_nothrow_constructible.h>
233+
# include <__type_traits/is_replaceable.h>
233234
# include <__type_traits/is_same.h>
234235
# include <__type_traits/is_swappable.h>
235236
# include <__type_traits/is_trivially_relocatable.h>
@@ -530,6 +531,10 @@ public:
530531
__libcpp_is_trivially_relocatable<__map>::value && __libcpp_is_trivially_relocatable<allocator_type>::value,
531532
deque,
532533
void>;
534+
using __replaceable _LIBCPP_NODEBUG =
535+
__conditional_t<__is_replaceable_v<__map> && __container_allocator_is_replaceable<__alloc_traits>::value,
536+
deque,
537+
void>;
533538

534539
static_assert(is_nothrow_default_constructible<allocator_type>::value ==
535540
is_nothrow_default_constructible<__pointer_allocator>::value,

libcxx/include/module.modulemap.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@ module std_core [system] {
272272
header "__type_traits/is_referenceable.h"
273273
export std_core.type_traits.integral_constant
274274
}
275+
module is_replaceable {
276+
header "__type_traits/is_replaceable.h"
277+
export std_core.type_traits.integral_constant
278+
}
275279
module is_same {
276280
header "__type_traits/is_same.h"
277281
export std_core.type_traits.integral_constant

libcxx/include/optional

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ namespace std {
210210
# include <__type_traits/is_nothrow_constructible.h>
211211
# include <__type_traits/is_object.h>
212212
# include <__type_traits/is_reference.h>
213+
# include <__type_traits/is_replaceable.h>
213214
# include <__type_traits/is_same.h>
214215
# include <__type_traits/is_scalar.h>
215216
# include <__type_traits/is_swappable.h>
@@ -590,6 +591,7 @@ public:
590591

591592
using __trivially_relocatable _LIBCPP_NODEBUG =
592593
conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, optional, void>;
594+
using __replaceable _LIBCPP_NODEBUG = conditional_t<__is_replaceable_v<_Tp>, optional, void>;
593595

594596
private:
595597
// Disable the reference extension using this static assert.

libcxx/include/string

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ basic_string<char32_t> operator""s( const char32_t *str, size_t len );
630630
# include <__type_traits/is_convertible.h>
631631
# include <__type_traits/is_nothrow_assignable.h>
632632
# include <__type_traits/is_nothrow_constructible.h>
633+
# include <__type_traits/is_replaceable.h>
633634
# include <__type_traits/is_same.h>
634635
# include <__type_traits/is_standard_layout.h>
635636
# include <__type_traits/is_trivially_constructible.h>
@@ -755,13 +756,20 @@ public:
755756
// external memory. In such cases, the destructor is responsible for unpoisoning
756757
// the memory to avoid triggering false positives.
757758
// Therefore it's crucial to ensure the destructor is called.
759+
//
760+
// However, it is replaceable since implementing move-assignment as a destroy + move-construct
761+
// will maintain the right ASAN state.
758762
using __trivially_relocatable = void;
759763
# else
760764
using __trivially_relocatable _LIBCPP_NODEBUG = __conditional_t<
761765
__libcpp_is_trivially_relocatable<allocator_type>::value && __libcpp_is_trivially_relocatable<pointer>::value,
762766
basic_string,
763767
void>;
764768
# endif
769+
using __replaceable _LIBCPP_NODEBUG =
770+
__conditional_t<__is_replaceable_v<pointer> && __container_allocator_is_replaceable<__alloc_traits>::value,
771+
basic_string,
772+
void>;
765773

766774
# if _LIBCPP_HAS_ASAN && _LIBCPP_INSTRUMENTED_WITH_ASAN
767775
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pointer __asan_volatile_wrapper(pointer const& __ptr) const {

libcxx/include/tuple

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ template <class... Types>
250250
# include <__type_traits/is_nothrow_assignable.h>
251251
# include <__type_traits/is_nothrow_constructible.h>
252252
# include <__type_traits/is_reference.h>
253+
# include <__type_traits/is_replaceable.h>
253254
# include <__type_traits/is_same.h>
254255
# include <__type_traits/is_swappable.h>
255256
# include <__type_traits/is_trivially_relocatable.h>
@@ -462,8 +463,8 @@ template <class _Indx, class... _Tp>
462463
struct __tuple_impl;
463464

464465
template <size_t... _Indx, class... _Tp>
465-
struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
466-
: public __tuple_leaf<_Indx, _Tp>... {
466+
struct _LIBCPP_DECLSPEC_EMPTY_BASES
467+
__tuple_impl<__tuple_indices<_Indx...>, _Tp...> : public __tuple_leaf<_Indx, _Tp>... {
467468
_LIBCPP_HIDE_FROM_ABI constexpr __tuple_impl() noexcept(
468469
__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
469470

@@ -555,6 +556,7 @@ class _LIBCPP_NO_SPECIALIZATIONS tuple {
555556
public:
556557
using __trivially_relocatable _LIBCPP_NODEBUG =
557558
__conditional_t<_And<__libcpp_is_trivially_relocatable<_Tp>...>::value, tuple, void>;
559+
using __replaceable _LIBCPP_NODEBUG = __conditional_t<_And<__is_replaceable<_Tp>...>::value, tuple, void>;
558560

559561
// [tuple.cnstr]
560562

libcxx/include/variant

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ namespace std {
246246
# include <__type_traits/is_nothrow_assignable.h>
247247
# include <__type_traits/is_nothrow_constructible.h>
248248
# include <__type_traits/is_reference.h>
249+
# include <__type_traits/is_replaceable.h>
249250
# include <__type_traits/is_same.h>
250251
# include <__type_traits/is_swappable.h>
251252
# include <__type_traits/is_trivially_assignable.h>
@@ -850,8 +851,7 @@ _LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
850851
_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
851852
_Trait::_Available,
852853
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __move_constructor(__move_constructor&& __that) noexcept(
853-
__all<is_nothrow_move_constructible_v<_Types>...>::value)
854-
: __move_constructor(__valueless_t{}) {
854+
__all<is_nothrow_move_constructible_v<_Types>...>::value) : __move_constructor(__valueless_t{}) {
855855
this->__generic_construct(*this, std::move(__that));
856856
} _LIBCPP_EAT_SEMICOLON);
857857

@@ -887,8 +887,9 @@ _LIBCPP_VARIANT_COPY_CONSTRUCTOR(
887887

888888
_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
889889
_Trait::_Available,
890-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor& __that)
891-
: __copy_constructor(__valueless_t{}) { this->__generic_construct(*this, __that); } _LIBCPP_EAT_SEMICOLON);
890+
_LIBCPP_HIDE_FROM_ABI
891+
_LIBCPP_CONSTEXPR_SINCE_CXX20 __copy_constructor(const __copy_constructor& __that) : __copy_constructor(
892+
__valueless_t{}) { this->__generic_construct(*this, __that); } _LIBCPP_EAT_SEMICOLON);
892893

893894
_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
894895
_Trait::_Unavailable,
@@ -1173,6 +1174,7 @@ class _LIBCPP_DECLSPEC_EMPTY_BASES _LIBCPP_NO_SPECIALIZATIONS variant
11731174
public:
11741175
using __trivially_relocatable _LIBCPP_NODEBUG =
11751176
conditional_t<_And<__libcpp_is_trivially_relocatable<_Types>...>::value, variant, void>;
1177+
using __replaceable _LIBCPP_NODEBUG = conditional_t<_And<__is_replaceable<_Types>...>::value, variant, void>;
11761178

11771179
template <bool _Dummy = true,
11781180
enable_if_t<__dependent_type<is_default_constructible<__first_type>, _Dummy>::value, int> = 0>
@@ -1576,8 +1578,8 @@ visit(_Visitor&& __visitor, _Vs&&... __vs) {
15761578

15771579
template <class... _Types>
15781580
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 auto
1579-
swap(variant<_Types...>& __lhs,
1580-
variant<_Types...>& __rhs) noexcept(noexcept(__lhs.swap(__rhs))) -> decltype(__lhs.swap(__rhs)) {
1581+
swap(variant<_Types...>& __lhs, variant<_Types...>& __rhs) noexcept(noexcept(__lhs.swap(__rhs)))
1582+
-> decltype(__lhs.swap(__rhs)) {
15811583
return __lhs.swap(__rhs);
15821584
}
15831585

0 commit comments

Comments
 (0)