]> granicus.if.org Git - re2c/commitdiff
Check accumulated parameter before entering recursion.
authorUlya Trofimovich <skvadrik@gmail.com>
Sat, 2 Jan 2016 17:27:45 +0000 (17:27 +0000)
committerUlya Trofimovich <skvadrik@gmail.com>
Sat, 2 Jan 2016 17:27:45 +0000 (17:27 +0000)
re2c/src/ir/skeleton/control_flow.cc
re2c/src/ir/skeleton/generate_data.cc
re2c/src/ir/skeleton/skeleton.h

index a015ffb5a19107a7ceab615dcc4a327f503c62fe..74166865fd6c51fbd4a09b050bb1fc57fad9deb0 100644 (file)
@@ -16,36 +16,27 @@ namespace re2c
 // We don't need all patterns that cause undefined behaviour.
 // We only need some examples, the shorter the better.
 // See also note [counting skeleton edges].
-Node::nakeds_t Node::naked_ways (way_t & prefix, std::vector<way_t> & ways)
+void Node::naked_ways (way_t & prefix, std::vector<way_t> & ways, nakeds_t &size)
 {
        if (!rule.rank.is_none ())
        {
-               return nakeds_t::from32(0u);
+               return;
        }
        else if (end ())
        {
                ways.push_back (prefix);
-               return nakeds_t::from64(prefix.size ());
+               size = size + nakeds_t::from64(prefix.size ());
        }
        else if (loop < 2)
        {
                local_inc _ (loop);
-               nakeds_t size = nakeds_t::from32(0u);
-               for (arcsets_t::iterator i = arcsets.begin (); i != arcsets.end (); ++i)
+               for (arcsets_t::iterator i = arcsets.begin ();
+                       i != arcsets.end () && !size.overflow (); ++i)
                {
                        prefix.push_back (&i->second);
-                       size = size + i->first->naked_ways (prefix, ways);
+                       i->first->naked_ways (prefix, ways, size);
                        prefix.pop_back ();
-                       if (size.overflow ())
-                       {
-                               return nakeds_t::limit ();
-                       }
                }
-               return size;
-       }
-       else
-       {
-               return nakeds_t::from32(0u);
        }
 }
 
@@ -53,12 +44,15 @@ void Skeleton::warn_undefined_control_flow ()
 {
        way_t prefix;
        std::vector<way_t> ways;
-       const bool overflow = nodes->naked_ways (prefix, ways).overflow ();
+       Node::nakeds_t size = Node::nakeds_t::from32(0u);
+
+       nodes->naked_ways (prefix, ways, size);
+
        if (!ways.empty ())
        {
-               warn.undefined_control_flow (line, cond, ways, overflow);
+               warn.undefined_control_flow (line, cond, ways, size.overflow ());
        }
-       else if (overflow)
+       else if (size.overflow ())
        {
                warn.fail (Warn::UNDEFINED_CONTROL_FLOW, line, "DFA is too large to check undefined control flow");
        }
index bebca17219e480810419a0115243cb6c690052f4..13e9f8a7f282534104dcd75246ec4dd5e7fe8046 100644 (file)
@@ -53,9 +53,8 @@ template <typename cunit_t, typename key_t>
  *
  */
 template <typename cunit_t, typename key_t>
-       Node::covers_t Node::cover (path_t & prefix, FILE * input, FILE * keys)
+       void Node::cover (path_t & prefix, FILE * input, FILE * keys, covers_t &size)
 {
-       covers_t size = covers_t::from32(0u);
        if (end () && suffix == NULL)
        {
                suffix = new path_t (rule, ctx);
@@ -63,20 +62,17 @@ template <typename cunit_t, typename key_t>
        if (suffix != NULL)
        {
                prefix.append (suffix);
-               size = cover_one<cunit_t, key_t> (input, keys, prefix);
+               size = size + cover_one<cunit_t, key_t> (input, keys, prefix);
        }
        else if (loop < 2)
        {
                local_inc _ (loop);
-               for (arcs_t::iterator i = arcs.begin (); i != arcs.end (); ++i)
+               for (arcs_t::iterator i = arcs.begin ();
+                       i != arcs.end () && !size.overflow(); ++i)
                {
                        path_t new_prefix = prefix;
                        new_prefix.extend (i->first->rule, i->first->ctx, &i->second);
-                       size = size + i->first->cover<cunit_t, key_t> (new_prefix, input, keys);
-                       if (size.overflow ())
-                       {
-                               return covers_t::limit ();
-                       }
+                       i->first->cover<cunit_t, key_t> (new_prefix, input, keys, size);
                        if (i->first->suffix != NULL && suffix == NULL)
                        {
                                suffix = new path_t (rule, ctx);
@@ -85,14 +81,17 @@ template <typename cunit_t, typename key_t>
                        }
                }
        }
-       return size;
 }
 
 template <typename cunit_t, typename key_t>
        void Skeleton::generate_paths_cunit_key (FILE * input, FILE * keys)
 {
        path_t prefix (nodes->rule, nodes->ctx);
-       if (nodes->cover<cunit_t, key_t> (prefix, input, keys).overflow ())
+       Node::covers_t size = Node::covers_t::from32(0u);
+
+       nodes->cover<cunit_t, key_t> (prefix, input, keys, size);
+
+       if (size.overflow ())
        {
                warning
                        ( NULL
index dedca8ac623608bd7412ee3fcaf2261ed2ee1ae8..8a754fd967e7d9e681e63e4fd553a80e589b09d6 100644 (file)
@@ -97,8 +97,8 @@ struct Node
        void calc_dist ();
        void calc_reachable ();
        template <typename cunit_t, typename key_t>
-               covers_t cover (path_t & prefix, FILE * input, FILE * keys);
-       nakeds_t naked_ways (way_t & prefix, std::vector<way_t> & ways);
+               void cover (path_t & prefix, FILE * input, FILE * keys, covers_t &size);
+       void naked_ways (way_t & prefix, std::vector<way_t> & ways, nakeds_t &size);
 
        FORBID_COPY (Node);
 };