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

Reply via email to