match_results::begin() and match_results::end() are required to work even when the object is not ready, so the current definition of end() is broken (it performs an undefined subtraction to return an invalid iterator).
PR libstdc++/83600 * include/bits/regex.h (match_results::end()): Return valid iterator when not ready. * testsuite/28_regex/match_results/ctors/char/default.cc: Check that unready objects are empty and have equal begin and end iterators. * testsuite/28_regex/match_results/ctors/wchar_t/default.cc: Likewise. Tested powerpc64le-linux, committed to trunk. Backports to follow.
commit 04afa2fa20058799ff24a18d798a0b2d054bb0aa Author: Jonathan Wakely <jwak...@redhat.com> Date: Wed Dec 27 21:53:54 2017 +0000 PR libstdc++/83600 fix end iterator for unready std::match_results PR libstdc++/83600 * include/bits/regex.h (match_results::end()): Return valid iterator when not ready. * testsuite/28_regex/match_results/ctors/char/default.cc: Check that unready objects are empty and have equal begin and end iterators. * testsuite/28_regex/match_results/ctors/wchar_t/default.cc: Likewise. diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h index 0d97d535e2a..d85be41f830 100644 --- a/libstdc++-v3/include/bits/regex.h +++ b/libstdc++-v3/include/bits/regex.h @@ -1749,7 +1749,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 */ const_iterator end() const - { return _Base_type::end() - 3; } + { return _Base_type::end() - (empty() ? 0 : 3); } /** * @brief Gets an iterator to one-past-the-end of the collection. diff --git a/libstdc++-v3/testsuite/28_regex/match_results/ctors/char/default.cc b/libstdc++-v3/testsuite/28_regex/match_results/ctors/char/default.cc index a6d1375df9e..c2177580ebb 100644 --- a/libstdc++-v3/testsuite/28_regex/match_results/ctors/char/default.cc +++ b/libstdc++-v3/testsuite/28_regex/match_results/ctors/char/default.cc @@ -30,6 +30,8 @@ void test01() std::cmatch cm; VERIFY( cm.size() == 0 ); VERIFY( !cm.ready() ); + VERIFY( cm.empty() ); + VERIFY( cm.begin() == cm.end() ); // PR libstdc++/83600 } void test02() @@ -37,6 +39,8 @@ void test02() std::smatch sm; VERIFY( sm.size() == 0 ); VERIFY( !sm.ready() ); + VERIFY( sm.empty() ); + VERIFY( sm.begin() == sm.end() ); // PR libstdc++/83600 } int diff --git a/libstdc++-v3/testsuite/28_regex/match_results/ctors/wchar_t/default.cc b/libstdc++-v3/testsuite/28_regex/match_results/ctors/wchar_t/default.cc index f1d0a3f1191..22e25e13f39 100644 --- a/libstdc++-v3/testsuite/28_regex/match_results/ctors/wchar_t/default.cc +++ b/libstdc++-v3/testsuite/28_regex/match_results/ctors/wchar_t/default.cc @@ -30,6 +30,8 @@ void test01() std::wcmatch cm; VERIFY( cm.size() == 0 ); VERIFY( !cm.ready() ); + VERIFY( cm.empty() ); + VERIFY( cm.begin() == cm.end() ); // PR libstdc++/83600 } void test02() @@ -37,6 +39,8 @@ void test02() std::wsmatch sm; VERIFY( sm.size() == 0 ); VERIFY( !sm.ready() ); + VERIFY( sm.empty() ); + VERIFY( sm.begin() == sm.end() ); // PR libstdc++/83600 } int