libstdc++: [_GLIBCXX_DEBUG] Fix std::__niter_wrap behavior     In _GLIBCXX_DEBUG mode the std::__niter_base can remove 2 layers, the     __gnu_debug::_Safe_iterator<> and the __gnu_cxx::__normal_iterator<>.     When std::__niter_wrap is called to build a __gnu_debug::_Safe_iterator<>     from a __gnu_cxx::__normal_iterator<> we then have a consistency issue     as the difference between the 2 iterators will done on a __normal_iterator     on one side and a C pointer on the other. To avoid this problem call     std::__niter_base on both input iterators.     libstdc++-v3/ChangeLog:             * include/bits/stl_algobase.h (std::__niter_wrap): Add a call to             std::__niter_base on res iterator. Tested under Linux x86_64 normal and _GLIBCXX_DEBUG modes in c++98, c++11, c++17. Ok to commit ? François On 19/02/2024 09:21, Jonathan Wakely wrote: > > > On Mon, 19 Feb 2024, 08:12 Jonathan Wakely, wrote: > > > > On Mon, 19 Feb 2024, 07:08 Stephan Bergmann, > wrote: > > On 2/17/24 15:14, François Dumont wrote: > > Thanks for the link, tested and committed. > > I assume this is the cause for the below failure now, > > > Yes, the new >= C++11 overload of __niter_base recursively unwraps > multiple layers of wrapping, so that a safe iterator wrapping a > normal iterator wrapping a pointer is unwrapped to just a pointer. > But then __niter_wrap doesn't restore both layers. > > > > Actually that's not the problem. __niter_wrap would restore both > layers, except that it uses __niter_base itself: > > >   347 |     { return __from + (__res - std::__niter_base(__from)); } > >       |  ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > And it seems to be getting called with the wrong types. Maybe that's > just a bug in std:: erase or maybe niter_wrap needs adjusting. > > I'll check in a couple of hours if François doesn't get to it first. > > I have to wonder how this wasn't caught by existing tests though. > > >