summaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2020-03-02 19:39:13 -0500
committerPatrick Palka <ppalka@redhat.com>2020-03-03 22:35:34 -0500
commit05779e2c89e06d09a6b685797e87723f7906a5ce (patch)
tree8fae04431c834ede3aa8d0c7e77a6525bb2274bf /libstdc++-v3
parent7f327e8765c25552a1a6ae7d8747f74786f243dd (diff)
libstdc++: Fix use of is_nothrow_assignable_v in <bits/ranges_uninitialized.h>
We are passing a value type as the first argument to is_nothrow_assignable_v, but the result of that is inevitably false. Since this predicate is a part of the condition that guards the corresponding optimizations for these algorithms, this bug means these optimizations are never used. We should be passing a reference type to is_nothrow_assignable_v instead. libstdc++-v3/ChangeLog: * include/bits/ranges_uninitialized.h (uninitialized_copy_fn::operator()): Pass a reference type as the first argument to is_nothrow_assignable_v. (uninitialized_copy_fn::operator()): Likewise. (uninitialized_move_fn::operator()): Likewise. Return an in_out_result with the input iterator stripped of its move_iterator. (uninitialized_move_n_fn::operator()): Likewise. (uninitialized_fill_fn::operator()): Pass a reference type as the first argument to is_nothrow_assignable_v. (uninitialized_fill_n_fn::operator()): Likewise.
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog13
-rw-r--r--libstdc++-v3/include/bits/ranges_uninitialized.h24
2 files changed, 27 insertions, 10 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 640c5be90ab..45ff06d4ea7 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,16 @@
+2020-03-04 Patrick Palka <ppalka@redhat.com>
+
+ * include/bits/ranges_uninitialized.h
+ (uninitialized_copy_fn::operator()): Pass a reference type as the first
+ argument to is_nothrow_assignable_v.
+ (uninitialized_copy_fn::operator()): Likewise.
+ (uninitialized_move_fn::operator()): Likewise. Return an in_out_result
+ with the input iterator stripped of its move_iterator.
+ (uninitialized_move_n_fn::operator()): Likewise.
+ (uninitialized_fill_fn::operator()): Pass a reference type as the first
+ argument to is_nothrow_assignable_v.
+ (uninitialized_fill_n_fn::operator()): Likewise.
+
2020-03-03 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/94013
diff --git a/libstdc++-v3/include/bits/ranges_uninitialized.h b/libstdc++-v3/include/bits/ranges_uninitialized.h
index 01e1cad646c..f97a07a9b4a 100644
--- a/libstdc++-v3/include/bits/ranges_uninitialized.h
+++ b/libstdc++-v3/include/bits/ranges_uninitialized.h
@@ -269,7 +269,7 @@ namespace ranges
if constexpr (sized_sentinel_for<_ISent, _Iter>
&& sized_sentinel_for<_OSent, _Out>
&& is_trivial_v<_OutType>
- && is_nothrow_assignable_v<_OutType,
+ && is_nothrow_assignable_v<_OutType&,
iter_reference_t<_Iter>>)
{
auto __d1 = ranges::distance(__ifirst, __ilast);
@@ -316,7 +316,7 @@ namespace ranges
using _OutType = remove_reference_t<iter_reference_t<_Out>>;
if constexpr (sized_sentinel_for<_Sent, _Out>
&& is_trivial_v<_OutType>
- && is_nothrow_assignable_v<_OutType,
+ && is_nothrow_assignable_v<_OutType&,
iter_reference_t<_Iter>>)
{
auto __d = ranges::distance(__ofirst, __olast);
@@ -354,13 +354,15 @@ namespace ranges
if constexpr (sized_sentinel_for<_ISent, _Iter>
&& sized_sentinel_for<_OSent, _Out>
&& is_trivial_v<_OutType>
- && is_nothrow_assignable_v<_OutType,
+ && is_nothrow_assignable_v<_OutType&,
iter_rvalue_reference_t<_Iter>>)
{
auto __d1 = ranges::distance(__ifirst, __ilast);
auto __d2 = ranges::distance(__ofirst, __olast);
- return ranges::copy_n(std::make_move_iterator(__ifirst),
- std::min(__d1, __d2), __ofirst);
+ auto [__in, __out]
+ = ranges::copy_n(std::make_move_iterator(__ifirst),
+ std::min(__d1, __d2), __ofirst);
+ return {std::move(__in).base(), __out};
}
else
{
@@ -404,12 +406,14 @@ namespace ranges
using _OutType = remove_reference_t<iter_reference_t<_Out>>;
if constexpr (sized_sentinel_for<_Sent, _Out>
&& is_trivial_v<_OutType>
- && is_nothrow_assignable_v<_OutType,
+ && is_nothrow_assignable_v<_OutType&,
iter_rvalue_reference_t<_Iter>>)
{
auto __d = ranges::distance(__ofirst, __olast);
- return ranges::copy_n(std::make_move_iterator(__ifirst),
- std::min(__n, __d), __ofirst);
+ auto [__in, __out]
+ = ranges::copy_n(std::make_move_iterator(__ifirst),
+ std::min(__n, __d), __ofirst);
+ return {std::move(__in).base(), __out};
}
else
{
@@ -436,7 +440,7 @@ namespace ranges
{
using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
if constexpr (is_trivial_v<_ValueType>
- && is_nothrow_assignable_v<_ValueType, const _Tp&>)
+ && is_nothrow_assignable_v<_ValueType&, const _Tp&>)
return ranges::fill(__first, __last, __x);
else
{
@@ -469,7 +473,7 @@ namespace ranges
{
using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
if constexpr (is_trivial_v<_ValueType>
- && is_nothrow_assignable_v<_ValueType, const _Tp&>)
+ && is_nothrow_assignable_v<_ValueType&, const _Tp&>)
return ranges::fill_n(__first, __n, __x);
else
{