]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR testsuite/61061 (FAIL: g++.dg/inherit/covariant7.C)
authorTim Shen <timshen@google.com>
Tue, 1 Jul 2014 03:05:45 +0000 (03:05 +0000)
committerTim Shen <timshen@gcc.gnu.org>
Tue, 1 Jul 2014 03:05:45 +0000 (03:05 +0000)
PR libstdc++/61061
PR libstdc++/61582
* include/bits/regex_automaton.h (_NFA<>::_M_insert_state): Add
a NFA state limit. If it's exceeded, regex_constants::error_space
will be throwed.
* include/bits/regex_automaton.tcc (_StateSeq<>::_M_clone): Use
map (which is sparse) instead of vector. This reduce n times clones'
cost from O(n^2) to O(n).
* include/std/regex: Add map dependency.
* testsuite/28_regex/algorithms/regex_match/ecma/char/61601.cc: New
testcase.

From-SVN: r212185

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/regex_automaton.h
libstdc++-v3/include/bits/regex_automaton.tcc
libstdc++-v3/include/std/regex
libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/61601.cc [new file with mode: 0644]

index 75e4841626cae67eb87395e039fda03622d7030f..3f4699fed1f005d08dce74f553c2e254bb7afa6a 100644 (file)
@@ -1,3 +1,17 @@
+2014-07-01  Tim Shen  <timshen@google.com>
+
+       PR libstdc++/61061
+       PR libstdc++/61582
+       * include/bits/regex_automaton.h (_NFA<>::_M_insert_state): Add
+       a NFA state limit. If it's exceeded, regex_constants::error_space
+       will be throwed.
+       * include/bits/regex_automaton.tcc (_StateSeq<>::_M_clone): Use
+       map (which is sparse) instead of vector. This reduce n times clones'
+       cost from O(n^2) to O(n).
+       * include/std/regex: Add map dependency.
+       * testsuite/28_regex/algorithms/regex_match/ecma/char/61601.cc: New
+       testcase.
+
 2014-07-01  Tim Shen  <timshen@google.com>
 
        PR libstdc++/61424
index 1b0da1453e955f2d7d296888c120b2b61c25f102..27ec671d86dc724ad5cfcaf1be9b81eedd64e41a 100644 (file)
  *  Do not attempt to use it directly. @headername{regex}
  */
 
+// This macro defines the maximal state number a NFA can have.
+#ifndef _GLIBCXX_REGEX_STATE_LIMIT
+#define _GLIBCXX_REGEX_STATE_LIMIT 100000
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 namespace __detail
@@ -254,6 +259,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_insert_state(_StateT __s)
       {
        this->push_back(std::move(__s));
+       if (this->size() > _GLIBCXX_REGEX_STATE_LIMIT)
+         __throw_regex_error(regex_constants::error_space);
        return this->size()-1;
       }
 
index 1c6cfdd1b9f25a75dd1d1043d4f515b4afd26fdc..08d271ec744ea416543df326264989bbd24e611c 100644 (file)
@@ -189,7 +189,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     _StateSeq<_TraitsT>
     _StateSeq<_TraitsT>::_M_clone()
     {
-      std::vector<_StateIdT> __m(_M_nfa.size(), -1);
+      std::map<_StateIdT, _StateIdT> __m;
       std::stack<_StateIdT> __stack;
       __stack.push(_M_start);
       while (!__stack.empty())
@@ -203,21 +203,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          if (__dup._M_opcode == _S_opcode_alternative
              || __dup._M_opcode == _S_opcode_repeat
              || __dup._M_opcode == _S_opcode_subexpr_lookahead)
-           if (__dup._M_alt != _S_invalid_state_id && __m[__dup._M_alt] == -1)
+           if (__dup._M_alt != _S_invalid_state_id
+               && __m.count(__dup._M_alt) == 0)
              __stack.push(__dup._M_alt);
          if (__u == _M_end)
            continue;
-         if (__dup._M_next != _S_invalid_state_id && __m[__dup._M_next] == -1)
+         if (__dup._M_next != _S_invalid_state_id
+             && __m.count(__dup._M_next) == 0)
            __stack.push(__dup._M_next);
        }
-      for (auto __v : __m)
+      for (auto __it : __m)
        {
-         if (__v == -1)
-           continue;
+         auto __v = __it.second;
          auto& __ref = _M_nfa[__v];
          if (__ref._M_next != _S_invalid_state_id)
            {
-             _GLIBCXX_DEBUG_ASSERT(__m[__ref._M_next] != -1);
+             _GLIBCXX_DEBUG_ASSERT(__m.count(__ref._M_next) > 0);
              __ref._M_next = __m[__ref._M_next];
            }
          if (__ref._M_opcode == _S_opcode_alternative
@@ -225,7 +226,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
              || __ref._M_opcode == _S_opcode_subexpr_lookahead)
            if (__ref._M_alt != _S_invalid_state_id)
              {
-               _GLIBCXX_DEBUG_ASSERT(__m[__ref._M_alt] != -1);
+               _GLIBCXX_DEBUG_ASSERT(__m.count(__ref._M_alt) > 0);
                __ref._M_alt = __m[__ref._M_alt];
              }
        }
index 9161f48354496c1864ad66258a002473052e359d..470772af66dce7e44fdf8f0591ecfd766c922cc0 100644 (file)
@@ -50,6 +50,7 @@
 #include <string>
 #include <utility>
 #include <vector>
+#include <map>
 #include <cstring>
 
 #include <bits/regex_constants.h>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/61601.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/61601.cc
new file mode 100644 (file)
index 0000000..88efab5
--- /dev/null
@@ -0,0 +1,48 @@
+// { dg-options "-std=gnu++11" }
+
+// Copyright (C) 2013-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.11.2 regex_match
+
+#include <regex>
+#include <testsuite_hooks.h>
+#include <testsuite_regex.h>
+
+using namespace __gnu_test;
+using namespace std;
+
+// libstdc++/61601
+void
+test01()
+{
+  try
+  {
+    regex r("((.*)$1{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100}{100})");
+  }
+  catch (const regex_error& e)
+  {
+    VERIFY(e.code() == regex_constants::error_space);
+  }
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}