On Tue, 21 Jul 2026 at 05:57, François Dumont <[email protected]> wrote: > > Here is the new commit message: > > libstdc++: [_GLIBCXX_DEBUG] Improve COW basic_string checks > > Put the __glibcxx_requires_valid_range checks at public member level > so that diagnostics are giving directly the culprit member name. > > Add the std::_RequireInputIter constraints on members taking template > iterator range to avoid the "do the right thing" ambiguity. > > libstdc++v3/ChangeLog: > > * include/bits/cow_string.h > (basic_string::_M_replace): New. > (basic_string(_InputIterator, _InputIterator, const _Alloc&): > Add std::_RequireInputIter constraint and > __glibcxx_requires_valid_constructor_range check. > (basic_string::append(_InputIte, _InputIte): Add > std::_RequireInputIter > constraint and __glibcxx_requires_valid_range check. Call > _M_replace. > (basic_string::assign(_InputIte, _InputIte): Likewise. > (basic_string::insert(iterator, _InputIte, _InputIte)): > Likewise. > (basic_string::replace(iterator, iterator, _InputIte, > _InputIte)): Likewise. > [__cplusplus >= 201103L](basic_string::_S_construct): New. > (basic_string::_M_replace_dispatch(iterator, iterator, > _InputIte, _InputIte, > __false_type)): Remove __glibcxx_requires_valid_range check. > * include/debug/debug.h > (__glibcxx_requires_valid_constructor_range): New. > > On 7/6/26 22:42, Jonathan Wakely wrote: > > On Mon, 15 Jun 2026 at 07:07 +0200, François Dumont wrote: > >> Hi > >> > >> libstdc++: [_GLIBCXX_DEBUG] Improve COW basic_string checks > >> > >> Put the __glibcxx_requires_valid_range checks at public member level > >> so that diagnostics are giving directly the invoked member name. > >> > >> Add the std::_RequireInputIter constraints on members taking > >> template > >> iterator range to avoid the "do the right thing" ambiguity > >> without the help of __is_integer. > >> > >> libstdc++v3/ChangeLog: > >> > >> * include/bits/cow_string.h > >> (basic_string::_M_replace): New. > >> (basic_string(_InputIterator, _InputIterator, const > >> _Alloc&): Add > >> std::_RequireInputIter constraint and > >> __glibcxx_requires_valid_constructor_range > > > > Please fix the line-wrapping here. Try to keep the lines to < 72 > > characters so that when indented by 'git log' they fit below 80. > > > >> check. > >> (basic_string::append(_InputIte, _InputIte): Add > >> std::_RequireInputIter > >> constraint and __glibcxx_requires_valid_range check. Call > >> _M_replace. > >> (basic_string::assign(_InputIte, _InputIte): Likewise. > >> (basic_string::insert(iterator, _InputIte, _InputIte)): > >> Likewise. > >> (basic_string::replace(iterator, iterator, _InputIte, > >> _InputIte)): Likewise. > >> [__cplusplus >= 201103L](basic_string::_S_construct): New. > >> (basic_string::_M_replace_dispatch(iterator, iterator, > >> _InputIte, _InputIte, > >> __false_type)): Remove __glibcxx_requires_valid_range check. > >> * include/debug/debug.h > >> (__glibcxx_requires_valid_constructor_range): New. > >> > >> Tested under Linux x86_64 with _GLIBCXX_USE_CXX11_ABI=0 and > >> _GLIBCXX_DEBUG. > > > > Did you test C++98 as well as the default -std modes? > > I hadn't but now did, ex: > > In function: > std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, > _Traits, _Alloc>::append(_InputIterator, _InputIterator) [with > _InputIterator = gnu_debug::_Safe_iterator<gnu_cxx:: > normal_iterator<char*, std::vector<char, std::allocator<char> > >, > std:: > debug::vector<char>, std::random_access_iterator_tag>; _CharT = char; > _Traits = std::char_traits<char>; _Alloc = std::allocator<char>] > > Error: function requires a valid iterator range [first, last). > > Objects involved in the operation: > iterator "first" @ 0x7ffc9027e5a0 { > type = gnu_cxx::normal_iterator<char*, std::vector<char, > std::allocator<char> > > (mutable iterator); > state = dereferenceable; > references sequence with type 'std::debug::vector<char, > std::allocator<char> >' @ 0x7ffc9027e750 > } > iterator "last" @ 0x7ffc9027e600 { > type = gnu_cxx::normal_iterator<char*, std::vector<char, > std::allocator<char> > > (mutable iterator); > state = dereferenceable; > references sequence with type 'std::debug::vector<char, > std::allocator<char> >' @ 0x7ffc9027e750 > } > XFAIL: 21_strings/basic_string/debug/append_neg.cc -std=gnu++98 > execution test > > > > > Doesn't this require new symbols to be exported by the linker script? > > > I don't think so. Maybe you had in mind the > __gnu_debug::__check_valid_range but that's a template function > implemented inline.
You've added a new member function, basic_string::_M_replace. Why doesn't that need to be exported from the shared library? Why don't the changes to the signature of basic_string::assign and basic_string::append change the exported symbols? > > Ok to commit ?
