]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Reduce use of debug containers in <regex>
authorJonathan Wakely <jwakely@redhat.com>
Mon, 9 Aug 2021 10:49:09 +0000 (11:49 +0100)
committerJonathan Wakely <jwakely@redhat.com>
Mon, 9 Aug 2021 19:46:56 +0000 (20:46 +0100)
The std::regex code uses std::map and std::vector, which means that when
_GLIBCXX_DEBUG is defined it uses the debug versions of those
containers. That no longer compiles, because I changed <regex> to
include <bits/stl_map.h> and <bits/stl_vector.h> instead of <map> and
<vector>, so the debug versions aren't defined, and std::map doesn't
compile. There is also a use of std::stack, which defaults to std::deque
which is the debug deque when _GLIBCXX_DEBUG is defined.

Using std::map, std::vector, and std::deque is probably a mistake, and
we should qualify them with _GLIBCXX_STD_C instead so that the debug
versions aren't used. We do not need the overhead of checking our own
uses of those containers, which should be correct anyway. The exception
is the vector base class of std::match_results, which exposes iterators
to users, so can benefit from debug mode checks for its iterators. For
other accesses to the vector elements, match_results already does its
own checks, so can access the _GLIBCXX_STD_C::vector base class
directly.

Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:

* include/bits/regex.h (basic_regex::transform_primary): Use
_GLIBCXX_STD_C::vector for local variable.
* include/bits/regex.tcc (__regex_algo_impl): Use reference to
_GLIBCXX_STD_C::vector base class of match_results.
* include/bits/regex_automaton.tcc (_StateSeq:_M_clone): Use
_GLIBCXX_STD_C::map and _GLIBCXX_STD_C::deque for local
variables.
* include/bits/regex_compiler.h (_BracketMatcher): Use
_GLIBCXX_STD_C::vector for data members.
* include/bits/regex_executor.h (_Executor): Likewise.
* include/std/regex [_GLIBCXX_DEBUG]: Include <debug/vector>.

libstdc++-v3/include/bits/regex.h
libstdc++-v3/include/bits/regex.tcc
libstdc++-v3/include/bits/regex_automaton.tcc
libstdc++-v3/include/bits/regex_compiler.h
libstdc++-v3/include/bits/regex_executor.h
libstdc++-v3/include/std/regex

index ac10fa184c651b9cb0151f319f4830d1b699d180..b8a0ad251d8bbb3ced020fc1936a618536071c6e 100644 (file)
@@ -257,7 +257,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
          // for details.
          typedef std::ctype<char_type> __ctype_type;
          const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
-         std::vector<char_type> __s(__first, __last);
+         _GLIBCXX_STD_C::vector<char_type> __s(__first, __last);
          __fctyp.tolower(__s.data(), __s.data() + __s.size());
          return this->transform(__s.data(), __s.data() + __s.size());
        }
@@ -1697,6 +1697,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
        * [n+3] suffix
        */
       typedef std::vector<sub_match<_Bi_iter>, _Alloc>     _Base_type;
+      // In debug mode _Base_type is the debug vector, this is the unsafe one:
+      typedef _GLIBCXX_STD_C::vector<sub_match<_Bi_iter>, _Alloc> _Unchecked;
       typedef std::iterator_traits<_Bi_iter>                      __iter_traits;
       typedef regex_constants::match_flag_type            match_flag_type;
 
@@ -1773,7 +1775,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
        * @retval true   The object has a fully-established result state.
        * @retval false  The object is not ready.
        */
-      bool ready() const noexcept { return !_Base_type::empty(); }
+      bool ready() const noexcept { return !_Unchecked::empty(); }
 
       /**
        * @name 28.10.2 Size
@@ -1791,11 +1793,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
        */
       size_type
       size() const noexcept
-      { return _Base_type::empty() ? 0 : _Base_type::size() - 3; }
+      { return _Unchecked::empty() ? 0 : _Unchecked::size() - 3; }
 
       size_type
       max_size() const noexcept
-      { return _Base_type::max_size() - 3; }
+      { return _Unchecked::max_size() - 3; }
 
       /**
        * @brief Indicates if the %match_results contains no results.
@@ -1869,7 +1871,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       {
        __glibcxx_assert( ready() );
        return __sub < size()
-              ? _Base_type::operator[](__sub)
+              ? _Unchecked::operator[](__sub)
               : _M_unmatched_sub();
       }
 
@@ -2045,7 +2047,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       // (plus additional objects for prefix, suffix and unmatched sub).
       void
       _M_resize(unsigned int __size)
-      { _Base_type::assign(__size + 3, sub_match<_Bi_iter>{}); }
+      { _Unchecked::assign(__size + 3, sub_match<_Bi_iter>{}); }
 
       // Set state to a failed match for the given past-the-end iterator.
       void
@@ -2053,32 +2055,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       {
        sub_match<_Bi_iter> __sm;
        __sm.first = __sm.second = __end;
-       _Base_type::assign(3, __sm);
+       _Unchecked::assign(3, __sm);
       }
 
       const_reference
       _M_unmatched_sub() const
-      { return _Base_type::operator[](_Base_type::size() - 3); }
+      { return _Unchecked::operator[](_Unchecked::size() - 3); }
 
       sub_match<_Bi_iter>&
       _M_unmatched_sub()
-      { return _Base_type::operator[](_Base_type::size() - 3); }
+      { return _Unchecked::operator[](_Unchecked::size() - 3); }
 
       const_reference
       _M_prefix() const
-      { return _Base_type::operator[](_Base_type::size() - 2); }
+      { return _Unchecked::operator[](_Unchecked::size() - 2); }
 
       sub_match<_Bi_iter>&
       _M_prefix()
-      { return _Base_type::operator[](_Base_type::size() - 2); }
+      { return _Unchecked::operator[](_Unchecked::size() - 2); }
 
       const_reference
       _M_suffix() const
-      { return _Base_type::operator[](_Base_type::size() - 1); }
+      { return _Unchecked::operator[](_Unchecked::size() - 1); }
 
       sub_match<_Bi_iter>&
       _M_suffix()
-      { return _Base_type::operator[](_Base_type::size() - 1); }
+      { return _Unchecked::operator[](_Unchecked::size() - 1); }
 
       _Bi_iter _M_begin;
       /// @endcond
index 39ad3f0a4cc2e949ae69e26dc13b4316a4b958cb..c8bdd377c1880f6f9412f9d6ba24a63bd8c0d8f2 100644 (file)
@@ -56,7 +56,7 @@ namespace __detail
       if (__re._M_automaton == nullptr)
        return false;
 
-      typename match_results<_BiIter, _Alloc>::_Base_type& __res = __m;
+      typename match_results<_BiIter, _Alloc>::_Unchecked& __res = __m;
       __m._M_begin = __s;
       __m._M_resize(__re._M_automaton->_M_sub_count());
 
@@ -66,7 +66,7 @@ namespace __detail
              && !__re._M_automaton->_M_has_backref))
        {
          _Executor<_BiIter, _Alloc, _TraitsT, false>
-           __executor(__s, __e, __m, __re, __flags);
+           __executor(__s, __e, __res, __re, __flags);
          if (__match_mode)
            __ret = __executor._M_match();
          else
@@ -75,7 +75,7 @@ namespace __detail
       else
        {
          _Executor<_BiIter, _Alloc, _TraitsT, true>
-           __executor(__s, __e, __m, __re, __flags);
+           __executor(__s, __e, __res, __re, __flags);
          if (__match_mode)
            __ret = __executor._M_match();
          else
index 0977f77892280e136a4f46a871309e13e76dab69..69f3ee5ba3c5dee16be85feba0c27312eba7ce80 100644 (file)
@@ -194,8 +194,8 @@ namespace __detail
     _StateSeq<_TraitsT>
     _StateSeq<_TraitsT>::_M_clone()
     {
-      std::map<_StateIdT, _StateIdT> __m;
-      std::stack<_StateIdT> __stack;
+      _GLIBCXX_STD_C::map<_StateIdT, _StateIdT> __m;
+      std::stack<_StateIdT, _GLIBCXX_STD_C::deque<_StateIdT>> __stack;
       __stack.push(_M_start);
       while (!__stack.empty())
        {
index bf7dcc54dba0194455d824e2d22339df6dc9d6dd..5b4f2ae35582f956fe6a884be42eb296073746cb 100644 (file)
@@ -538,10 +538,10 @@ namespace __detail
       { }
 
     private:
-      std::vector<_CharT>                       _M_char_set;
-      std::vector<_StringT>                     _M_equiv_set;
-      std::vector<pair<_StrTransT, _StrTransT>> _M_range_set;
-      std::vector<_CharClassT>                  _M_neg_class_set;
+      _GLIBCXX_STD_C::vector<_CharT>            _M_char_set;
+      _GLIBCXX_STD_C::vector<_StringT>          _M_equiv_set;
+      _GLIBCXX_STD_C::vector<pair<_StrTransT, _StrTransT>> _M_range_set;
+      _GLIBCXX_STD_C::vector<_CharClassT>       _M_neg_class_set;
       _CharClassT                               _M_class_set;
       _TransT                                   _M_translator;
       const _TraitsT&                           _M_traits;
index 014b4e830647c44da9c1752e182cdc979bfa60ba..3422893371aced05a7c694a89a07af1460c1956c 100644 (file)
@@ -60,7 +60,7 @@ namespace __detail
     public:
       typedef typename iterator_traits<_BiIter>::value_type _CharT;
       typedef basic_regex<_CharT, _TraitsT>                 _RegexT;
-      typedef std::vector<sub_match<_BiIter>, _Alloc>       _ResultsVec;
+      typedef _GLIBCXX_STD_C::vector<sub_match<_BiIter>, _Alloc> _ResultsVec;
       typedef regex_constants::match_flag_type              _FlagT;
       typedef typename _TraitsT::char_class_type            _ClassT;
       typedef _NFA<_TraitsT>                                _NFAT;
@@ -215,7 +215,7 @@ namespace __detail
          _BiIter* _M_get_sol_pos() { return nullptr; }
 
          // Saves states that need to be considered for the next character.
-         vector<pair<_StateIdT, _ResultsVec>>  _M_match_queue;
+         _GLIBCXX_STD_C::vector<pair<_StateIdT, _ResultsVec>> _M_match_queue;
          // Indicates which states are already visited.
          bool*     _M_visited_states;
          // To record current solution.
@@ -248,7 +248,7 @@ namespace __detail
       const _RegexT&                                        _M_re;
       const _NFAT&                                          _M_nfa;
       _ResultsVec&                                          _M_results;
-      vector<pair<_BiIter, int>>                            _M_rep_count;
+      _GLIBCXX_STD_C::vector<pair<_BiIter, int>>            _M_rep_count;
       _State_info<__search_mode, _ResultsVec>              _M_states;
       _FlagT                                                _M_flags;
       // Do we have a solution so far?
index 04fb8b2d9714dc85ba434a5c895d754fd13f5bef..2c94fa306c291c25301707d53d4eae840e3c78ba 100644 (file)
@@ -55,6 +55,9 @@
 #include <bits/stl_vector.h>
 #include <bits/stl_bvector.h>
 #include <bits/vector.tcc>
+#ifdef _GLIBCXX_DEBUG
+# include <debug/vector>
+#endif
 #include <bits/regex_constants.h>
 #include <bits/regex_error.h>
 #include <bits/regex_automaton.h>