On Thu, Feb 19, 2026 at 7:48 PM Avi Kivity <[email protected]> wrote:
> > > On Tue, Feb 17, 2026 at 12:31 PM Avi Kivity <[email protected]> wrote: > >> >> >> On Tue, Feb 17, 2026 at 11:44 AM Jonathan Wakely <[email protected]> >> wrote: >> >>> >>> >>> On Mon, 16 Feb 2026, 19:48 Avi Kivity, <[email protected]> wrote: >>> >>>> >>>> >>>> On Mon, Feb 16, 2026 at 8:29 PM Jonathan Wakely <[email protected]> >>>> wrote: >>>> >>>>> On Mon, 16 Feb 2026 at 17:59, Avi Kivity <[email protected]> wrote: >>>>> > >>>>> > std::uninitialized_move{,_n} delegates to the corresponding >>>>> > std::uninitialized_copy() variant after wrapping with a move >>>>> > iterator, but the std::uninitialized_copy() doesn't unwrap the >>>>> > move iterator, therefore losing the memcpy optimization if the >>>>> > iterators were just pointers. >>>>> > >>>>> > Fix this by unwrapping the move iterator using __miter_base(). To >>>>> > prevent some greedy_ops tests starting to fail by consuming the >>>>> > pointer difference, we have to unwrap the move iterator before >>>>> computing >>>>> > the iterator difference as well. >>>>> > >>>>> > libstdc++v3/Changelog: >>>>> > >>>>> > PR libstdc++/121789 >>>>> > * include/bits/stl_uninitialized.h (uninitialized_copy): >>>>> > Unwrap move iterators >>>>> > * >>>>> testsuite/20_util/specialized_algorithms/uninitialized_move/121789.cc: >>>>> > New test. >>>>> > --- >>>>> > >>>>> > Disclosure: I was assisted by AI. >>>>> > >>>>> > libstdc++-v3/include/bits/stl_uninitialized.h | 8 ++-- >>>>> > .../uninitialized_move/121789.cc | 37 >>>>> +++++++++++++++++++ >>>>> > 2 files changed, 42 insertions(+), 3 deletions(-) >>>>> > create mode 100644 >>>>> libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_move/121789.cc >>>>> > >>>>> > diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h >>>>> b/libstdc++-v3/include/bits/stl_uninitialized.h >>>>> > index 82e4ba2ff7b..fa9d896fefc 100644 >>>>> > --- a/libstdc++-v3/include/bits/stl_uninitialized.h >>>>> > +++ b/libstdc++-v3/include/bits/stl_uninitialized.h >>>>> > @@ -273,11 +273,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >>>>> > // We cannot tell when this condition is true in general, >>>>> > // so we rely on the __memcpyable trait. >>>>> > >>>>> > #if __cplusplus >= 201103L >>>>> > using _Dest = decltype(std::__niter_base(__result)); >>>>> > - using _Src = decltype(std::__niter_base(__first)); >>>>> > + using _Src = >>>>> decltype(std::__miter_base(std::__niter_base(__first))); >>>>> > using _ValT = typename >>>>> iterator_traits<_ForwardIterator>::value_type; >>>>> > >>>>> > #if __glibcxx_raw_memory_algorithms >= 202411L // >= C++26 >>>>> > if consteval { >>>>> > return std::__do_uninit_copy(__first, __last, __result); >>>>> > @@ -285,16 +285,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >>>>> > #endif >>>>> > if constexpr (!__is_trivially_constructible(_ValT, >>>>> decltype(*__first))) >>>>> > return std::__do_uninit_copy(__first, __last, __result); >>>>> > else if constexpr (__memcpyable<_Dest, _Src>::__value) >>>>> > { >>>>> > - ptrdiff_t __n = __last - __first; >>>>> > + ptrdiff_t __n >>>>> > + = std::__miter_base(std::__niter_base(__last)) >>>>> > + - std::__miter_base(std::__niter_base(__first)); >>>>> >>>>> This change seems completely unnecessary (I blame the AI assistance). >>>>> >>>>> >>>> It is necessary. Without it, 23_containers/vector/types/1.cc will not >>>> compile since greedy_ops' >>>> operator- will fight with the move iterator's operator-. I mentioned it >>>> in the commit changelog. >>>> >>> >>> But that's more evidence that the greedy_ops tests are invalid C++. >>> >> >> Shall I send a patch to remove them? >> >> >>> Or if we still care about them, we should fix move_iterator. >>> >>> >> I can't make that call. >> >> > How should I proceed? Patch greedy_ops out of existence, or keep this line? > > Personally I think this line is fine (if we're happy to unwrap to get the > pointer, we should be happy to unwrap to get the range size), AND that > attempting to harden against something like greedy_ops is futile. > > > Pinging for direction.
