[PATCH] libstdc++/ranges: Fix more wrong value type init from reference type [PR111861]
Jonathan Wakely
jwakely@redhat.com
Wed Sep 17 15:10:20 GMT 2025
On Wed, 17 Sept 2025 at 16:08, Patrick Palka <ppalka@redhat.com> wrote:
>
> On Wed, 17 Sep 2025, Jonathan Wakely wrote:
>
> > On Wed, 17 Sept 2025 at 15:19, Patrick Palka <ppalka@redhat.com> wrote:
> > >
> > > Tested on x86_64-pc-linux-gnu, does this look OK for trunk/15/14?
> > >
> > > -- >8 --
> > >
> > > As in r16-3912-g412a1f78b53709, this fixes some other spots where we
> > > wrongly use a deduced type and non-direct-initialization when intending
> > > to initialize a value type from an iterator's reference type.
> > >
> > > PR libstdc++/111861
> > >
> > > libstdc++-v3/ChangeLog:
> > >
> > > * include/bits/ranges_algo.h (ranges::unique_copy): When
> > > initializing a value type object from *iter, use
> > > direct-initialization and don't use a deduced type.
> > > (ranges::push_heap): Use direct-initialization when initializing
> > > a value type object from ranges::iter_move.
> > > (ranges::max): As in ranges::unique_copy.
> > > * include/bits/ranges_util.h (ranges::min): Likewise.
> > > ---
> > > libstdc++-v3/include/bits/ranges_algo.h | 8 ++++----
> > > libstdc++-v3/include/bits/ranges_util.h | 2 +-
> > > 2 files changed, 5 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h
> > > index 4025bba9f204..eebad9e1621c 100644
> > > --- a/libstdc++-v3/include/bits/ranges_algo.h
> > > +++ b/libstdc++-v3/include/bits/ranges_algo.h
> > > @@ -1529,7 +1529,7 @@ namespace ranges
> > > }
> > > else // indirectly_copyable_storable<_Iter, _Out>
> > > {
> > > - auto __value = *__first;
> > > + iter_value_t<_Iter> __value(*__first);
> > > *__result = __value;
> > > while (++__first != __last)
> > > {
> > > @@ -2075,9 +2075,9 @@ namespace ranges
> > > else
> > > {
> > > auto __comp_proj = __detail::__make_comp_proj(__comp, __proj);
> > > + iter_value_t<_Iter> __value(ranges::iter_move(ranges::prev(__last)));
> > > __detail::__push_heap(__first, (__last - __first) - 1,
> > > - 0, ranges::iter_move(ranges::prev(__last)),
> > > - __comp_proj);
> > > + 0, __value, __comp_proj);
> >
> > Should this be std::move(__value)?
>
> Oops, fixed.
>
> >
> > I find it quite painful that the standard allows iterators to return a
> > proxy that doesn't implicitly convert to the value type. Or that
> > ranges::iter_move doesn't do the conversion and guarantee to return
> > value_type or a real reference to value_type, instead of returning the
> > proxy reference. It makes it quite difficult to write correct code.
>
> Yeah :/
>
> How does the below look? This is probably not worth backporting
> actually. I doubt this causes problems in practice.
OK for trunk, and I agree that it's unlikely to matter to anybody, so
not important to backport.
>
> -- >8 --
>
> Subject: [PATCH] libstdc++/ranges: Fix more wrong value type init from
> reference type [PR111861]
>
> PR libstdc++/111861
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/ranges_algo.h (ranges::unique_copy): When
> initializing a value type object from *iter, use
> direct-initialization and don't use a deduced type.
> (ranges::push_heap): Use direct-initialization when initializing
> a value type object from ranges::iter_move.
> (ranges::max): As in ranges::unique_copy.
> * include/bits/ranges_util.h (ranges::min): Likewise.
> ---
> libstdc++-v3/include/bits/ranges_algo.h | 8 ++++----
> libstdc++-v3/include/bits/ranges_util.h | 2 +-
> 2 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h
> index 4025bba9f204..5c9fe627aee0 100644
> --- a/libstdc++-v3/include/bits/ranges_algo.h
> +++ b/libstdc++-v3/include/bits/ranges_algo.h
> @@ -1529,7 +1529,7 @@ namespace ranges
> }
> else // indirectly_copyable_storable<_Iter, _Out>
> {
> - auto __value = *__first;
> + iter_value_t<_Iter> __value(*__first);
> *__result = __value;
> while (++__first != __last)
> {
> @@ -2075,9 +2075,9 @@ namespace ranges
> else
> {
> auto __comp_proj = __detail::__make_comp_proj(__comp, __proj);
> + iter_value_t<_Iter> __value(ranges::iter_move(ranges::prev(__last)));
> __detail::__push_heap(__first, (__last - __first) - 1,
> - 0, ranges::iter_move(ranges::prev(__last)),
> - __comp_proj);
> + 0, std::move(__value), __comp_proj);
> return __last;
> }
> }
> @@ -4219,7 +4219,7 @@ namespace ranges
> auto __first = ranges::begin(__r);
> auto __last = ranges::end(__r);
> __glibcxx_assert(__first != __last);
> - auto __result = *__first;
> + range_value_t<_Range> __result(*__first);
> while (++__first != __last)
> {
> auto&& __tmp = *__first;
> diff --git a/libstdc++-v3/include/bits/ranges_util.h b/libstdc++-v3/include/bits/ranges_util.h
> index 84de258908ea..2aa8938edf25 100644
> --- a/libstdc++-v3/include/bits/ranges_util.h
> +++ b/libstdc++-v3/include/bits/ranges_util.h
> @@ -761,7 +761,7 @@ namespace ranges
> auto __first = ranges::begin(__r);
> auto __last = ranges::end(__r);
> __glibcxx_assert(__first != __last);
> - auto __result = *__first;
> + range_value_t<_Range> __result(*__first);
> while (++__first != __last)
> {
> auto&& __tmp = *__first;
> --
> 2.51.0.268.ga483264b01
>
More information about the Libstdc++
mailing list