https://gcc.gnu.org/g:c0b659db1adcf84c04629cd8aeda89f1d2047e2a
commit r16-8392-gc0b659db1adcf84c04629cd8aeda89f1d2047e2a Author: François Dumont <[email protected]> Date: Mon Mar 30 22:18:50 2026 +0200 libstdc++: [_GLIBCXX_DEBUG] Fix COW string valid range check In revision 698a6af5dcbae5d935bcda8a461dea8458c658dc the _GLIBCXX_DEBUG code for the Library Defect 438 has been removed as starting in C++11 the iterator type is constrained through the _RequireInputIter requirement. But the COW basic_string implementation used when _GLIBCXX_USE_CXX11_ABI=0 is missing the _RequireInputIter constraint on a number of methods resulting in test failures. For the moment move the culprit __glibcxx_requires_valid_range call in the COW basic_string implementation in a method where the iterator type has already been checked. libstdc++-v3/ChangeLog: * include/bits/cow_string.h (basic_string::replace(iterator, iterator, _InputIte, _InputIte)): Move __glibcxx_requires_valid_range to... (basic_string::_M_replace_dispatch(iterator, iterator, _InputIte, _InputIte, __fase_type)): ...here. * testsuite/21_strings/basic_string/debug/append_neg.cc: New test case. * testsuite/21_strings/basic_string/debug/assign_neg.cc: New test case. * testsuite/21_strings/basic_string/debug/construct_neg.cc: New test case. * testsuite/21_strings/basic_string/debug/insert_neg.cc: New test case. * testsuite/21_strings/basic_string/debug/replace_neg.cc: New test case. Co-authored-by: Jonathan Wakely <[email protected]> Reviewed-by: Jonathan Wakely <[email protected]> Diff: --- libstdc++-v3/include/bits/cow_string.h | 2 +- .../21_strings/basic_string/debug/append_neg.cc | 19 +++++++++++++++++++ .../21_strings/basic_string/debug/assign_neg.cc | 19 +++++++++++++++++++ .../21_strings/basic_string/debug/construct_neg.cc | 17 +++++++++++++++++ .../21_strings/basic_string/debug/insert_neg.cc | 19 +++++++++++++++++++ .../21_strings/basic_string/debug/replace_neg.cc | 20 ++++++++++++++++++++ 6 files changed, 95 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/include/bits/cow_string.h b/libstdc++-v3/include/bits/cow_string.h index 6cf002243729..df71185e556d 100644 --- 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"); diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/debug/append_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string/debug/append_neg.cc new file mode 100644 index 000000000000..befe83a84f35 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/debug/append_neg.cc @@ -0,0 +1,19 @@ +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <vector> +#include <string> + +void test01() +{ + std::vector<char> v1(10, 'a'); + std::string s2; + + s2.append(v1.begin() + 7, v1.begin() + 2); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/debug/assign_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string/debug/assign_neg.cc new file mode 100644 index 000000000000..5f32c170f504 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/debug/assign_neg.cc @@ -0,0 +1,19 @@ +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <vector> +#include <string> + +void test01() +{ + std::vector<char> v1(10, 'a'); + std::string s2; + + s2.assign(v1.begin() + 7, v1.begin() + 2); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/debug/construct_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string/debug/construct_neg.cc new file mode 100644 index 000000000000..1ac933d43091 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/debug/construct_neg.cc @@ -0,0 +1,17 @@ +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <vector> +#include <string> + +void test01() +{ + std::vector<char> v1(10, 'a'); + std::string s2(v1.begin() + 7, v1.begin() + 2); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/debug/insert_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string/debug/insert_neg.cc new file mode 100644 index 000000000000..95530ef2a510 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/debug/insert_neg.cc @@ -0,0 +1,19 @@ +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <vector> +#include <string> + +void test01() +{ + std::vector<char> v1(10, 'a'); + std::string s2; + + s2.insert(s2.begin(), v1.begin() + 7, v1.begin() + 2); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/debug/replace_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string/debug/replace_neg.cc new file mode 100644 index 000000000000..fd3df9e8539e --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string/debug/replace_neg.cc @@ -0,0 +1,20 @@ +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <vector> +#include <string> + +void test01() +{ + std::vector<char> v1(10, 'a'); + std::string s2 = "bbbbbbbbbb"; + + s2.replace(s2.begin(), s2.begin() + 5, + v1.begin() + 7, v1.begin() + 2); +} + +int main() +{ + test01(); + return 0; +}
