[PATCH] libsdc++: Enable asserts in repeat_view::_Iterator uncoditionally.

Tomasz Kaminski tkaminsk@redhat.com
Fri Sep 18 15:08:04 GMT 2026


On Fri, Sep 18, 2026 at 5:02 PM Jonathan Wakely <jwakely@redhat.com> wrote:

> On Fri, 18 Sept 2026 at 15:50, Tomasz Kamiński <tkaminsk@redhat.com>
> wrote:
> >
> > The checks against _M_current being negive were disabled for cases where
> > _Bound denotes unreachable_sentinel_t. However, _M_current has ptrdiff_t
> > type in that case, and this check are as meaningfull are for integer
> bound.
>
> The standard seems to suggest that it's OK to pass a negative bound
> for an unreachable sentinel.
>
> Preconditions: If Bound is not unreachable_sentinel_t, b ≥ 0.
>
If you mean this one: https://eel.is/c++draft/range.repeat#iterator-2
It's an exposition-only private constructor, and a negative bound is never
passed to it as you would hit UB in constructors:
https://eel.is/c++draft/range.repeat#view-1

>
> This change would cause assertions for the code that isn't forbidden
> by the standard. Or am I missing something?
>
>
> >
> > libstdc++-v3/ChangeLog:
> >
> >         * include/std/ranges (repeat_view::_Iterator::_Iterator)
> >         (repeat_view::_Iterator::operator--)
> >         (repeat_view::_Iterator::operator+=)
> >         (repeat_view::_Iterator::operator-=): Unconditionally assert
> >         on _M_current having non-negative value.
> > ---
> > Noticed that when working on extracting _Repeat_iterator (that I
> > templated with _IndexType). Worth to be separate.
> >
> > Testing on x86_64-linux. *repeat* view passed with all standard
> > modes, debug and assertions. OK for trunk?
> >
> >  libstdc++-v3/include/std/ranges | 14 ++++----------
> >  1 file changed, 4 insertions(+), 10 deletions(-)
> >
> > diff --git a/libstdc++-v3/include/std/ranges
> b/libstdc++-v3/include/std/ranges
> > index 1c0991cae13..a0ce157d4f2 100644
> > --- a/libstdc++-v3/include/std/ranges
> > +++ b/libstdc++-v3/include/std/ranges
> > @@ -8075,10 +8075,7 @@ namespace views::__adaptor
> >      constexpr explicit
> >      _Iterator(const _Tp* __value, __index_type __bound = __index_type())
> >      : _M_value(__value), _M_current(__bound)
> > -    {
> > -      if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
> > -       __glibcxx_assert(__bound >= 0);
> > -    }
> > +    { __glibcxx_assert(__bound >= 0); }
> >
> >      friend repeat_view;
> >
> > @@ -8112,8 +8109,7 @@ namespace views::__adaptor
> >      constexpr _Iterator&
> >      operator--()
> >      {
> > -      if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
> > -       __glibcxx_assert(_M_current > 0);
> > +      __glibcxx_assert(_M_current > 0);
> >        --_M_current;
> >        return *this;
> >      }
> > @@ -8129,8 +8125,7 @@ namespace views::__adaptor
> >      constexpr _Iterator&
> >      operator+=(difference_type __n)
> >      {
> > -      if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
> > -       __glibcxx_assert(_M_current + __n >= 0);
> > +      __glibcxx_assert(_M_current + __n >= 0);
> >        _M_current += __n;
> >        return *this;
> >      }
> > @@ -8138,8 +8133,7 @@ namespace views::__adaptor
> >      constexpr _Iterator&
> >      operator-=(difference_type __n)
> >      {
> > -      if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
> > -       __glibcxx_assert(_M_current - __n >= 0);
> > +      __glibcxx_assert(_M_current - __n >= 0);
> >        _M_current -= __n;
> >        return *this;
> >      }
> > --
> > 2.55.0
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20260918/77c277e6/attachment.htm>


More information about the Libstdc++ mailing list