[PATCH][_GLIBCXX_DEBUG][__cplusplus >= 201103L] Remove useless workaround

Jonathan Wakely jwakely@redhat.com
Mon Mar 23 09:12:48 GMT 2026


On Mon, 23 Mar 2026 at 05:50, François Dumont <frs.dumont@gmail.com> wrote:
>
> So _GLIBCXX_USE_CXX11_ABI=0 was the solution to this mystery, I was
> going crazy, thanks Jonathan for spotting this.
>
>
> On 3/21/26 17:18, Jonathan Wakely wrote:
> > On Sat, 21 Mar 2026 at 16:03, Jonathan Wakely <jwakely@redhat.com> wrote:
> >> On Sat, 21 Mar 2026 at 13:45, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
> >>>
> >>>
> >>> On Sat, 21 Mar 2026, 13:36 François Dumont, <frs.dumont@gmail.com> wrote:
> >>>> Still no chance to reproduce this problem.
> >>>>
> >>>> I think the patch is good and that you are simply missing it in the below build.
> >>>>
> >>>> The compiler is reporting the error coming from:
> >>>>
> >>>> /home/tkaminsk/build/gcc/16/x86_64-pc-linux-gnu/libstdc++-v3/include/debug/string:238:   required from '__gnu_debug::basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator, _InputIterator, const _Allocator&) [with _InputIterator = int; _CharT = char; _Traits = std::char_traits<char>; _Allocator = std::allocator<char>]'
> >>>>
> >>>> Line 238 is the former line of the call to __glibcxx_check_valid_constructor_range(__begin, __end) that is leading to the error.
> >>>>
> >>>> After my patch it is on line 243.
> >>>
> >>> Tomasz and I are both testing current trunk. If we're missing your patch, then it means it hasn't been pushed to trunk.
> >> I see the problem, the errors are with -D_GLIBCXX_USE_CXX11_ABI=0 and
> >> -D_GLIBCXX_DEBUG
> >>
> >> e.g.
> >> make check RUNTESTFLAGS="conformance.exp=28_regex/match_results/swap.cc
> >> --target_board=unix/-D_GLIBCXX_USE_CXX11_ABI=0/
> >> -D_GLIBCXX_DEBUG"
> > The COW string has this function, which doesn't care if it's called
> > with iterators or integers, because it dispatches to
> > _M_replace_dispatch:
> >
> >        template<class _InputIterator>
> >      basic_string&
> >      replace(iterator __i1, iterator __i2,
> >          _InputIterator __k1, _InputIterator __k2)
> >      {
> >        _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
> >                     && __i2 <= _M_iend());
> >        __glibcxx_requires_valid_range(__k1, __k2);
> >        typedef typename std::__is_integer<_InputIterator>::__type _Integral;
> >        return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());
> >      }
> >
> > Calling __glibcxx_requires_valid_range gives an error, because that is
> > no longer valid for non-iterators.
> >
> > We should just move the __glibcxx_requires_valid_range to the correct
> > _M_replace_dispatch function, like this:
> >
> > --- a/libstdc++-v3/include/bits/cow_string.h
> > +++ b/libstdc++-v3/include/bits/cow_string.h
> > @@ -2124,7 +2124,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >         {
> >           _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
> >                                    && __i2 <= _M_iend());
> > -         __glibcxx_requires_valid_range(__k1, __k2);
> >           typedef typename std::__is_integer<_InputIterator>::__type _Integral;
> >           return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());
> >         }
> > @@ -3833,6 +3832,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >        _M_replace_dispatch(iterator __i1, iterator __i2, _InputIterator __k1,
> >                           _InputIterator __k2, __false_type)
> >        {
> > +       __glibcxx_requires_valid_range(__k1, __k2);
> >         const basic_string __s(__k1, __k2);
> >         const size_type __n1 = __i2 - __i1;
> >         _M_check_length(__n1, __s.size(), "basic_string::_M_replace_dispatch");
> >
> Could be a solution, but usually the _GLIBCXX_DEBUG checks are done
> directly behind the public api so that the assertion is showing it
> instead of a nested method.
>
> I'll propose an alternative approach if there's no rush.

We can do this, but it's uglier:

--- a/libstdc++-v3/include/bits/cow_string.h
+++ b/libstdc++-v3/include/bits/cow_string.h
@@ -2124,8 +2124,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
         _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
                                  && __i2 <= _M_iend());
-         __glibcxx_requires_valid_range(__k1, __k2);
-         typedef typename std::__is_integer<_InputIterator>::__type _Integral;
+         typedef std::__is_integer<_InputIterator> _IsIntegral;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
+         if _GLIBCXX_CONSTEXPR (!_IsIntegral::__value)
+           __glibcxx_requires_valid_range(__k1, __k2);
+#pragma GCC diagnostic pop
+         typedef typename _IsIntegral::__type _Integral;
         return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());
       }



More information about the Libstdc++ mailing list