diff mbox

[libstdc++/64302,libstdc++/64303] Fix match_results iterators and regex_token_iterator

Message ID CAG4ZjNm0eOP5FwcBUdEds4wWhpFYp7+NrS=QeJP4=vK1Tzxj1w@mail.gmail.com
State New
Headers show

Commit Message

Tim Shen Dec. 14, 2014, 11:23 p.m. UTC
Bootstraped and tested :)

I'm not sure if it's safe to directly backport it to 4.9, since one
inline function (_M_normalize_result) is added; but at least we can
manually inline them by copy & paste.

Comments

Jonathan Wakely Dec. 15, 2014, 10:58 a.m. UTC | #1
On 14/12/14 15:23 -0800, Tim Shen wrote:
>Bootstraped and tested :)
>
>I'm not sure if it's safe to directly backport it to 4.9, since one
>inline function (_M_normalize_result) is added; but at least we can
>manually inline them by copy & paste.

It's OK for trunk and 4.9, without changes.

Code compiled against 4.9.2 that inlines some of the regex code won't
be affected by the added function. Code that doesn't inline the code
will start calling the new function. So it won't hurt and might help.
diff mbox

Patch

diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h
index 3afec37..80b1de8 100644
--- a/libstdc++-v3/include/bits/regex.h
+++ b/libstdc++-v3/include/bits/regex.h
@@ -1756,7 +1756,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
        */
       const_iterator
       cbegin() const
-      { return _Base_type::cbegin() + 2; }
+      { return this->begin(); }
 
       /**
        * @brief Gets an iterator to one-past-the-end of the collection.
@@ -1770,7 +1770,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
        */
       const_iterator
       cend() const
-      { return _Base_type::cend(); }
+      { return this->end(); }
 
       //@}
 
@@ -2632,7 +2632,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 			     regex_constants::match_flag_type __m
 			     = regex_constants::match_default)
       : _M_position(__a, __b, __re, __m),
-      _M_subs(__submatches, *(&__submatches+1)), _M_n(0)
+      _M_subs(__submatches, __submatches + _Nm), _M_n(0)
       { _M_init(__a, __b); }
 
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -2660,12 +2660,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
        */
       regex_token_iterator(const regex_token_iterator& __rhs)
       : _M_position(__rhs._M_position), _M_subs(__rhs._M_subs),
-      _M_suffix(__rhs._M_suffix), _M_n(__rhs._M_n), _M_result(__rhs._M_result),
-      _M_has_m1(__rhs._M_has_m1)
-      {
-	if (__rhs._M_result == &__rhs._M_suffix)
-	  _M_result = &_M_suffix;
-      }
+      _M_suffix(__rhs._M_suffix), _M_n(__rhs._M_n), _M_has_m1(__rhs._M_has_m1)
+      { _M_normalize_result(); }
 
       /**
        * @brief Assigns a %regex_token_iterator to another.
@@ -2737,6 +2733,18 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_end_of_seq() const
       { return _M_result == nullptr; }
 
+      // [28.12.2.2.4]
+      void
+      _M_normalize_result()
+      {
+	if (_M_position != _Position())
+	  _M_result = &_M_current_match();
+	else if (_M_has_m1)
+	  _M_result = &_M_suffix;
+	else
+	  _M_result = nullptr;
+      }
+
       _Position         _M_position;
       std::vector<int>  _M_subs;
       value_type        _M_suffix;
diff --git a/libstdc++-v3/include/bits/regex.tcc b/libstdc++-v3/include/bits/regex.tcc
index b676428..0206a6c 100644
--- a/libstdc++-v3/include/bits/regex.tcc
+++ b/libstdc++-v3/include/bits/regex.tcc
@@ -607,11 +607,9 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_position = __rhs._M_position;
       _M_subs = __rhs._M_subs;
       _M_n = __rhs._M_n;
-      _M_result = __rhs._M_result;
       _M_suffix = __rhs._M_suffix;
       _M_has_m1 = __rhs._M_has_m1;
-      if (__rhs._M_result == &__rhs._M_suffix)
-	_M_result = &_M_suffix;
+      _M_normalize_result();
       return *this;
     }
 
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/64303.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/64303.cc
new file mode 100644
index 0000000..f09bbe1
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/64303.cc
@@ -0,0 +1,49 @@ 
+// { dg-do run }
+// { dg-options "-std=gnu++11" }
+
+//
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.12.2 Class template regex_token_iterator
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  const std::string s("  111  222  ");
+  const std::regex re("\\w+");
+
+  std::sregex_token_iterator it1(s.begin(), s.end(), re), it2(it1), end;
+
+  for (; it1 != end; ++it1, ++it2) {
+    VERIFY(it1 == it2);
+    VERIFY(*it1 == *it2);
+  }
+  VERIFY(it2 == end);
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}