From: Ulya Trofimovich Date: Sat, 2 Jan 2016 17:27:45 +0000 (+0000) Subject: Check accumulated parameter before entering recursion. X-Git-Tag: 0.16~1^2~15 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ec0a3f36ef000d121b15325917786689fc5605cb;p=re2c Check accumulated parameter before entering recursion. --- diff --git a/re2c/src/ir/skeleton/control_flow.cc b/re2c/src/ir/skeleton/control_flow.cc index a015ffb5..74166865 100644 --- a/re2c/src/ir/skeleton/control_flow.cc +++ b/re2c/src/ir/skeleton/control_flow.cc @@ -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 & ways) +void Node::naked_ways (way_t & prefix, std::vector & 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 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"); } diff --git a/re2c/src/ir/skeleton/generate_data.cc b/re2c/src/ir/skeleton/generate_data.cc index bebca172..13e9f8a7 100644 --- a/re2c/src/ir/skeleton/generate_data.cc +++ b/re2c/src/ir/skeleton/generate_data.cc @@ -53,9 +53,8 @@ template * */ template - 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 if (suffix != NULL) { prefix.append (suffix); - size = cover_one (input, keys, prefix); + size = size + cover_one (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 (new_prefix, input, keys); - if (size.overflow ()) - { - return covers_t::limit (); - } + i->first->cover (new_prefix, input, keys, size); if (i->first->suffix != NULL && suffix == NULL) { suffix = new path_t (rule, ctx); @@ -85,14 +81,17 @@ template } } } - return size; } template void Skeleton::generate_paths_cunit_key (FILE * input, FILE * keys) { path_t prefix (nodes->rule, nodes->ctx); - if (nodes->cover (prefix, input, keys).overflow ()) + Node::covers_t size = Node::covers_t::from32(0u); + + nodes->cover (prefix, input, keys, size); + + if (size.overflow ()) { warning ( NULL diff --git a/re2c/src/ir/skeleton/skeleton.h b/re2c/src/ir/skeleton/skeleton.h index dedca8ac..8a754fd9 100644 --- a/re2c/src/ir/skeleton/skeleton.h +++ b/re2c/src/ir/skeleton/skeleton.h @@ -97,8 +97,8 @@ struct Node void calc_dist (); void calc_reachable (); template - covers_t cover (path_t & prefix, FILE * input, FILE * keys); - nakeds_t naked_ways (way_t & prefix, std::vector & ways); + void cover (path_t & prefix, FILE * input, FILE * keys, covers_t &size); + void naked_ways (way_t & prefix, std::vector & ways, nakeds_t &size); FORBID_COPY (Node); };