Bootstrapped and tested on x86-pc-linux-gnu debug. It is a conformance fix, but I don't think it's very important. I'm happy to backport it to gcc 5/4.9, but if it's not considered necessary, I'm Ok as well.
Thanks! -- Regards, Tim Shen
commit 7f4f729d5dd80050ff966398e28909a40fb57932 Author: Tim Shen <tims...@google.com> Date: Thu Apr 21 21:02:11 2016 -0700 PR libstdc++/70745 * include/bits/regex_executor.tcc (_Executor<>::_M_word_boundary): Fix the match_not_bow and match_not_eow behavior. * testsuite/28_regex/regression.cc: Add testcase. diff --git a/libstdc++-v3/include/bits/regex_executor.tcc b/libstdc++-v3/include/bits/regex_executor.tcc index 2abd020..6bbcb1b 100644 --- a/libstdc++-v3/include/bits/regex_executor.tcc +++ b/libstdc++-v3/include/bits/regex_executor.tcc @@ -413,6 +413,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>:: _M_word_boundary() const { + if (_M_current == _M_begin && (_M_flags & regex_constants::match_not_bow)) + return false; + if (_M_current == _M_end && (_M_flags & regex_constants::match_not_eow)) + return false; + bool __left_is_word = false; if (_M_current != _M_begin || (_M_flags & regex_constants::match_prev_avail)) @@ -424,13 +429,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool __right_is_word = _M_current != _M_end && _M_is_word(*_M_current); - if (__left_is_word == __right_is_word) - return false; - if (__left_is_word && !(_M_flags & regex_constants::match_not_eow)) - return true; - if (__right_is_word && !(_M_flags & regex_constants::match_not_bow)) - return true; - return false; + return __left_is_word != __right_is_word; } _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/testsuite/28_regex/regression.cc b/libstdc++-v3/testsuite/28_regex/regression.cc index c9a3402..d367c8b 100644 --- a/libstdc++-v3/testsuite/28_regex/regression.cc +++ b/libstdc++-v3/testsuite/28_regex/regression.cc @@ -45,7 +45,20 @@ test02() "/ghci" }; auto rx = std::regex(re_str, std::regex_constants::grep | std::regex_constants::icase); - VERIFY(std::regex_search("/abcd", rx)); + VERIFY(regex_search_debug("/abcd", rx)); +} + +void +test03() +{ + bool test __attribute__((unused)) = true; + + VERIFY(regex_match_debug("a.", regex(R"(a\b.)"), regex_constants::match_not_eow)); + VERIFY(regex_match_debug(".a", regex(R"(.\ba)"), regex_constants::match_not_bow)); + VERIFY(regex_search_debug("a", regex(R"(^\b)"))); + VERIFY(regex_search_debug("a", regex(R"(\b$)"))); + VERIFY(!regex_search_debug("a", regex(R"(^\b)"), regex_constants::match_not_bow)); + VERIFY(!regex_search_debug("a", regex(R"(\b$)"), regex_constants::match_not_eow)); } int @@ -53,6 +66,7 @@ main() { test01(); test02(); + test03(); return 0; }