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++. Or if
we still care about them, we should fix move_iterator.

We need to be able to subtract two move_iterator objects. That's a
requirement for random access iterators.



> Perhaps std::distance() is better here.
>
>
>
>>
>> >           if (__n > 0) [[__likely__]]
>> >             {
>> >               using _ValT = typename remove_pointer<_Src>::type;
>> >               __builtin_memcpy(std::__niter_base(__result),
>> > -                              std::__niter_base(__first),
>> > +
>> std::__miter_base(std::__niter_base(__first)),
>> >                                __n * sizeof(_ValT));
>> >               __result += __n;
>> >             }
>> >           return __result;
>> >         }
>> > diff --git
>> a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_move/121789.cc
>> b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_move/121789.cc
>> > new file mode 100644
>> > index 00000000000..7ac8cf6496f
>> > --- /dev/null
>> > +++
>> b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_move/121789.cc
>> > @@ -0,0 +1,37 @@
>> > +// Copyright (C) 2025-2026 Free Software Foundation, Inc.
>>
>> There should not be any copyright/license header here, see
>> https://gcc.gnu.org/onlinedocs/libstdc++/manual/test.html#test.new_tests
>>
>>
> I can remove it. The test was inspired by other tests in the directory, so
> copying was involved.
>
> I do have FSF copyright assignment, at least for glibc/binutils, not sure
> about gcc.
>
>
>
>> > +//
>> > +// This file is part of the GNU ISO C++ Library.  This library is free
>> > +// software; you can redistribute it and/or modify it under the
>> > +// terms of the GNU General Public License as published by the
>> > +// Free Software Foundation; either version 3, or (at your option)
>> > +// any later version.
>> > +
>> > +// This library is distributed in the hope that it will be useful,
>> > +// but WITHOUT ANY WARRANTY; without even the implied warranty of
>> > +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> > +// GNU General Public License for more details.
>> > +
>> > +// You should have received a copy of the GNU General Public License
>> along
>> > +// with this library; see the file COPYING3.  If not see
>> > +// <http://www.gnu.org/licenses/>.
>> > +
>> > +// { dg-options "-O1 -fdump-tree-optimized" }
>> > +// { dg-do compile { target c++17 } }
>> > +// { dg-final { scan-tree-dump "memcpy" "optimized" } }
>> > +
>> > +// PR libstdc++/121789
>> > +// std::uninitialized_move_n() and friends don't optimize to memcpy
>> > +
>> > +#include <memory>
>> > +
>> > +struct T { int x; };
>> > +
>> > +void f(T* src, T* dst, unsigned n)
>> > +{
>> > +  std::uninitialized_move(src, src + n, dst);
>> > +}
>> > +
>> > +void g(T* src, T* dst, unsigned n)
>> > +{
>> > +  std::uninitialized_move_n(src, n, dst);
>> > +}
>> > --
>> > 2.53.0
>> >
>>
>>

Reply via email to