regex.h (regex_iterator::regex_iterator()): Define end() as _M_pregex == nullptr.
authorTim Shen <timshen@google.com>
Wed, 9 Nov 2016 22:11:32 +0000 (22:11 +0000)
committerTim Shen <timshen@gcc.gnu.org>
Wed, 9 Nov 2016 22:11:32 +0000 (22:11 +0000)
* libstdc++-v3/include/bits/regex.h (regex_iterator::regex_iterator()):
Define end() as _M_pregex == nullptr.
* libstdc++-v3/include/bits/regex.tcc (regex_iterator::operator==(),
regex_iterator::operator++()): Fix operator==() and operator++() to
look at null-ness of _M_pregex on both sides.
* testsuite/28_regex/regression.cc: New testcase.

From-SVN: r242025

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/regex.h
libstdc++-v3/include/bits/regex.tcc
libstdc++-v3/testsuite/28_regex/regression.cc

index 61dafba43e9b6aa36bdcd5bd9169039dcace350f..f405ccd15691add3412c7c0cd1de14f8a317b80f 100644 (file)
@@ -1,3 +1,12 @@
+2016-11-09  Tim Shen  <timshen@google.com>
+
+       * libstdc++-v3/include/bits/regex.h (regex_iterator::regex_iterator()):
+       Define end() as _M_pregex == nullptr.
+       * libstdc++-v3/include/bits/regex.tcc (regex_iterator::operator==(),
+       regex_iterator::operator++()): Fix operator==() and operator++() to
+       look at null-ness of _M_pregex on both sides.
+       * testsuite/28_regex/regression.cc: New testcase.
+
 2016-11-07  Jason Merrill  <jason@redhat.com>
 
        * include/bits/c++config (_GLIBCXX_NOEXCEPT_PARM)
index a7d45e6edc47a1604b7fac0a2e1d1fec8c5344a7..aadf312cfc0c5f03b95f5a4c72dbc06d7a048a1a 100644 (file)
@@ -2454,7 +2454,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
        * one-past-the-end of a range.
        */
       regex_iterator()
-      : _M_match()
+      : _M_pregex()
       { }
 
       /**
index 4a3d7c36cf8fbe9063c5a9b3e3c1dd12c7173e82..3f8969d1611a5c1c1c6c52172b9968e4d489119f 100644 (file)
@@ -496,12 +496,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     regex_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
     operator==(const regex_iterator& __rhs) const
     {
-      return (_M_match.empty() && __rhs._M_match.empty())
-       || (_M_begin == __rhs._M_begin
-           && _M_end == __rhs._M_end
-           && _M_pregex == __rhs._M_pregex
-           && _M_flags == __rhs._M_flags
-           && _M_match[0] == __rhs._M_match[0]);
+      if (_M_pregex == nullptr && __rhs._M_pregex == nullptr)
+       return true;
+      return _M_pregex == __rhs._M_pregex
+         && _M_begin == __rhs._M_begin
+         && _M_end == __rhs._M_end
+         && _M_flags == __rhs._M_flags
+         && _M_match[0] == __rhs._M_match[0];
     }
 
   template<typename _Bi_iter,
@@ -525,7 +526,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            {
              if (__start == _M_end)
                {
-                 _M_match = value_type();
+                 _M_pregex = nullptr;
                  return *this;
                }
              else
@@ -558,7 +559,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
              _M_match._M_begin = _M_begin;
            }
          else
-           _M_match = value_type();
+           _M_pregex = nullptr;
        }
       return *this;
     }
index effb356075e0cfb52a8fb494cd2ce7169257a4f9..5214fe3dbc293ef0e038c7d6f38ccf0c3cb7ec0d 100644 (file)
@@ -72,6 +72,27 @@ test05()
   VERIFY(regex_match_debug("-", std::regex("[a-]")));
 }
 
+// PR libstdc++/78236
+void
+test06()
+{
+  char const s[] = "afoo";
+  std::basic_regex<char> r("(f+)");
+  {
+    std::cregex_iterator i(s, s+sizeof(s), r);
+    std::cregex_iterator j(s, s+sizeof(s), r);
+    VERIFY(i == j);
+  }
+  // The iterator manipulation code must be repeated in the same scope
+  // to expose the undefined read during the execution of the ==
+  // operator (stack location reuse)
+  {
+    std::cregex_iterator i(s, s+sizeof(s), r);
+    std::cregex_iterator j;
+    VERIFY(!(i == j));
+  }
+}
+
 int
 main()
 {
@@ -80,6 +101,7 @@ main()
   test03();
   test04();
   test05();
+  test06();
   return 0;
 }