2017-05-18 Jonathan Wakely <jwakely@redhat.com>
+ Backport from mainline
+ 2016-11-09 Tim Shen <timshen@google.com>
+
+ PR libstdc++/78236
+ * 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.
+
Backport from mainline
2016-12-15 Jonathan Wakely <jwakely@redhat.com>
* one-past-the-end of a range.
*/
regex_iterator()
- : _M_match()
+ : _M_pregex()
{ }
/**
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,
{
if (__start == _M_end)
{
- _M_match = value_type();
+ _M_pregex = nullptr;
return *this;
}
else
_M_match._M_begin = _M_begin;
}
else
- _M_match = value_type();
+ _M_pregex = nullptr;
}
return *this;
}
VERIFY(std::regex_search("/abcd", rx));
}
+// 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()
{
test01();
test02();
+ test06();
return 0;
}