// 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);
}
}
{
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");
}
*
*/
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);
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);
}
}
}
- 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
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);
};