aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2021-10-11 09:07:15 +0100
committerJonathan Wakely <jwakely@redhat.com>2021-10-11 20:34:16 +0100
commit84088dc4bb6a546c896a068dc201463493babf43 (patch)
tree1b9cda7ec87970a26092a41745ce184fd3907ce6
parent008e7397dad971c03c08fc1b0a4a98fddccaaed8 (diff)
downloadgcc-84088dc4bb6a546c896a068dc201463493babf43.zip
gcc-84088dc4bb6a546c896a068dc201463493babf43.tar.gz
gcc-84088dc4bb6a546c896a068dc201463493babf43.tar.bz2
libstdc++: Fix std::match_results::end() for failed matches [PR102667]
The end() function needs to consider whether the underlying vector is empty, not whether the match_results object is empty. That's because the underlying vector will always contain at least three elements for a match_results object that is "ready". It contains three extra elements which are stored in the vector but are not considered part of sequence, and so should not be part of the [begin(),end()) range. libstdc++-v3/ChangeLog: PR libstdc++/102667 * include/bits/regex.h (match_result::empty()): Optimize by calling the base function directly. (match_results::end()): Check _Base_type::empty() not empty(). * testsuite/28_regex/match_results/102667.C: New test.
-rw-r--r--libstdc++-v3/include/bits/regex.h4
-rw-r--r--libstdc++-v3/testsuite/28_regex/match_results/102667.C39
2 files changed, 41 insertions, 2 deletions
diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h
index ff908da..bf02bff 100644
--- a/libstdc++-v3/include/bits/regex.h
+++ b/libstdc++-v3/include/bits/regex.h
@@ -1828,7 +1828,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
_GLIBCXX_NODISCARD bool
empty() const noexcept
- { return size() == 0; }
+ { return _Unchecked::size() <= 3; }
///@}
@@ -1946,7 +1946,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
*/
const_iterator
end() const noexcept
- { return _Base_type::end() - (empty() ? 0 : 3); }
+ { return _Base_type::end() - (_Base_type::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/102667.C b/libstdc++-v3/testsuite/28_regex/match_results/102667.C
new file mode 100644
index 0000000..9e38c9e
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/match_results/102667.C
@@ -0,0 +1,39 @@
+// { dg-do run { target c++11 } }
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ std::cmatch sm;
+ VERIFY( sm.empty() );
+ VERIFY( sm.size() == 0 );
+ VERIFY( sm.begin() == sm.end() ); // PR libstdc++/83600
+
+ bool matched = std::regex_match("a", sm, std::regex("b"));
+ VERIFY( ! matched );
+ VERIFY( sm.ready() );
+ VERIFY( sm.empty() );
+ VERIFY( sm.size() == 0 );
+ VERIFY( sm.begin() == sm.end() ); // PR libstdc++/102667
+
+ matched = std::regex_match("a", sm, std::regex("a"));
+ VERIFY( matched );
+ VERIFY( sm.ready() );
+ VERIFY( ! sm.empty() );
+ VERIFY( sm.size() == 1 );
+ VERIFY( (sm.end() - sm.begin()) == 1 );
+
+ matched = std::regex_search("abcd", sm, std::regex("(b)(c)"));
+ VERIFY( matched );
+ VERIFY( sm.ready() );
+ VERIFY( ! sm.empty() );
+ VERIFY( sm.size() == 3 );
+ VERIFY( (sm.end() - sm.begin()) == 3 );
+}
+
+int main()
+{
+ test01();
+}