Commit a4d3bfc0 by David Malcolm

analyzer: add enode status and revamp __analyzer_dump_exploded_nodes

The analyzer recognizes __analyzer_dump_exploded_nodes as a "magic"
function for use in DejaGnu tests: at the end of the pass, it issues
a warning at each such call, dumping the count of exploded nodes seen at
the call, which can be checked in test cases via dg-warning directives,
along with the IDs of the enodes (which is helpful when debugging).

My intent was to give a way of testing the results of the state-merging
code.

The state-merging code can generate duplicate exploded nodes at a point
when state merging occurs, taking a pair of enodes from the worklist
that share a program_point and sufficiently similar state.  For these
cases it generates a merged state, and adds edges from those enodes to
the merged-state enode (potentially a new or a pre-existing enode); the
input enodes don't have process_node called on them.

This means that at a CFG join point there can be an unpredictable number
of enodes that we don't care about, where the precise number depends on
the details of the state-merger code, immediately followed by a more
predictable number that we do care about.

I've been papering over this in the analyzer DejaGnu tests somewhat
by adding pairs of __analyzer_dump_exploded_nodes calls at CFG join
points, where the output at the first call is somewhat arbitrary, and
the second has the number we care about; the first number tends to
change "at random" as I tweak the state merging code, in ways that
aren't interesting, but require the tests to be updated.

See e.g. gcc.dg/analyzer/paths-6.c which had:

  __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
  // FIXME: the above can vary between 2 and 3 exploded nodes
  __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */

This patch remedies this situation by tracking which enodes are
processed, and which are merely "merger" enodes.  It updates the
output for __analyzer_dump_exploded_nodes so that count of enodes
only includes the *processed* enodes, and that the IDs are split
into "processed" and "merger" enodes.

The patch simplifies the testsuite by eliminating the redundant calls
described above; the example above becomes:

  __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */

where the output in question is now:

  warning: 1 processed enode: [EN: 94] merger(s): [EN: 93]

The patch also adds various checks on the status of enodes, to ensure
e.g. that each enode is processed at most once.

gcc/analyzer/ChangeLog:
	* engine.cc (exploded_node::dump_dot): Show merger enodes.
	(worklist::add_node): Assert that the node's m_status is
	STATUS_WORKLIST.
	(exploded_graph::process_worklist): Likewise for nodes from the
	worklist.  Set status of merged nodes to STATUS_MERGER.
	(exploded_graph::process_node): Set status of node to
	STATUS_PROCESSED.
	(exploded_graph::dump_exploded_nodes): Rework handling of
	"__analyzer_dump_exploded_nodes", splitting enodes by status into
	"processed" and "merger", showing the count of just the processed
	enodes at the call, rather than the count of all enodes.
	* exploded-graph.h (exploded_node::status): New enum.
	(exploded_node::exploded_node): Initialize m_status to
	STATUS_WORKLIST.
	(exploded_node::get_status): New getter.
	(exploded_node::set_status): New setter.
	(exploded_node::m_status): New field.

gcc/ChangeLog:
	* doc/analyzer.texi
	(Special Functions for Debugging the Analyzer): Update description
	of __analyzer_dump_exploded_nodes.

gcc/testsuite/ChangeLog:
	* gcc.dg/analyzer/data-model-1.c: Update for changed output to
	__analyzer_dump_exploded_nodes, dropping redundant call at merger.
	* gcc.dg/analyzer/data-model-7.c: Likewise.
	* gcc.dg/analyzer/loop-2.c: Update for changed output format.
	* gcc.dg/analyzer/loop-2a.c: Likewise.
	* gcc.dg/analyzer/loop-4.c: Likewise.
	* gcc.dg/analyzer/loop.c: Likewise.
	* gcc.dg/analyzer/malloc-paths-10.c: Likewise; drop redundant
	call at merger.
	* gcc.dg/analyzer/malloc-vs-local-1a.c: Likewise.
	* gcc.dg/analyzer/malloc-vs-local-1b.c: Likewise.
	* gcc.dg/analyzer/malloc-vs-local-2.c: Likewise.
	* gcc.dg/analyzer/malloc-vs-local-3.c: Likewise.
	* gcc.dg/analyzer/paths-1.c: Likewise.
	* gcc.dg/analyzer/paths-1a.c: Likewise.
	* gcc.dg/analyzer/paths-2.c: Likewise.
	* gcc.dg/analyzer/paths-3.c: Likewise.
	* gcc.dg/analyzer/paths-4.c: Update for changed output format.
	* gcc.dg/analyzer/paths-5.c: Likewise.
	* gcc.dg/analyzer/paths-6.c: Likewise; drop redundant calls
	at merger.
	* gcc.dg/analyzer/paths-7.c: Likewise.
	* gcc.dg/analyzer/torture/conditionals-2.c: Update for changed
	output format.
	* gcc.dg/analyzer/zlib-1.c: Likewise; drop redundant calls.
	* gcc.dg/analyzer/zlib-5.c: Update for changed output format.
parent b7b3378f
2020-02-05 David Malcolm <dmalcolm@redhat.com>
* doc/analyzer.texi
(Special Functions for Debugging the Analyzer): Update description
of __analyzer_dump_exploded_nodes.
2020-02-05 Jakub Jelinek <jakub@redhat.com> 2020-02-05 Jakub Jelinek <jakub@redhat.com>
PR target/92190 PR target/92190
......
2020-02-05 David Malcolm <dmalcolm@redhat.com>
* engine.cc (exploded_node::dump_dot): Show merger enodes.
(worklist::add_node): Assert that the node's m_status is
STATUS_WORKLIST.
(exploded_graph::process_worklist): Likewise for nodes from the
worklist. Set status of merged nodes to STATUS_MERGER.
(exploded_graph::process_node): Set status of node to
STATUS_PROCESSED.
(exploded_graph::dump_exploded_nodes): Rework handling of
"__analyzer_dump_exploded_nodes", splitting enodes by status into
"processed" and "merger", showing the count of just the processed
enodes at the call, rather than the count of all enodes.
* exploded-graph.h (exploded_node::status): New enum.
(exploded_node::exploded_node): Initialize m_status to
STATUS_WORKLIST.
(exploded_node::get_status): New getter.
(exploded_node::set_status): New setter.
2020-02-04 David Malcolm <dmalcolm@redhat.com> 2020-02-04 David Malcolm <dmalcolm@redhat.com>
PR analyzer/93543 PR analyzer/93543
......
...@@ -827,6 +827,8 @@ exploded_node::dump_dot (graphviz_out *gv, const dump_args_t &args) const ...@@ -827,6 +827,8 @@ exploded_node::dump_dot (graphviz_out *gv, const dump_args_t &args) const
pp_write_text_to_stream (pp); pp_write_text_to_stream (pp);
pp_printf (pp, "EN: %i", m_index); pp_printf (pp, "EN: %i", m_index);
if (m_status == STATUS_MERGER)
pp_string (pp, " (merger)");
pp_newline (pp); pp_newline (pp);
format f (true); format f (true);
...@@ -1638,6 +1640,7 @@ worklist::peek_next () ...@@ -1638,6 +1640,7 @@ worklist::peek_next ()
void void
worklist::add_node (exploded_node *enode) worklist::add_node (exploded_node *enode)
{ {
gcc_assert (enode->get_status () == exploded_node::STATUS_WORKLIST);
m_queue.insert (key_t (*this, enode), enode); m_queue.insert (key_t (*this, enode), enode);
} }
...@@ -2124,6 +2127,7 @@ exploded_graph::process_worklist () ...@@ -2124,6 +2127,7 @@ exploded_graph::process_worklist ()
while (m_worklist.length () > 0) while (m_worklist.length () > 0)
{ {
exploded_node *node = m_worklist.take_next (); exploded_node *node = m_worklist.take_next ();
gcc_assert (node->get_status () == exploded_node::STATUS_WORKLIST);
gcc_assert (node->m_succs.length () == 0 gcc_assert (node->m_succs.length () == 0
|| node == m_origin); || node == m_origin);
...@@ -2136,6 +2140,8 @@ exploded_graph::process_worklist () ...@@ -2136,6 +2140,8 @@ exploded_graph::process_worklist ()
if (flag_analyzer_state_merge && node != m_origin) if (flag_analyzer_state_merge && node != m_origin)
if (exploded_node *node_2 = m_worklist.peek_next ()) if (exploded_node *node_2 = m_worklist.peek_next ())
{ {
gcc_assert (node_2->get_status ()
== exploded_node::STATUS_WORKLIST);
gcc_assert (node->m_succs.length () == 0); gcc_assert (node->m_succs.length () == 0);
gcc_assert (node_2->m_succs.length () == 0); gcc_assert (node_2->m_succs.length () == 0);
...@@ -2181,6 +2187,7 @@ exploded_graph::process_worklist () ...@@ -2181,6 +2187,7 @@ exploded_graph::process_worklist ()
/* Remove node_2 from the worklist. */ /* Remove node_2 from the worklist. */
m_worklist.take_next (); m_worklist.take_next ();
node_2->set_status (exploded_node::STATUS_MERGER);
/* Continue processing "node" below. */ /* Continue processing "node" below. */
} }
...@@ -2190,6 +2197,7 @@ exploded_graph::process_worklist () ...@@ -2190,6 +2197,7 @@ exploded_graph::process_worklist ()
in the worklist, to be processed on the next in the worklist, to be processed on the next
iteration. */ iteration. */
add_edge (node, node_2, NULL, change); add_edge (node, node_2, NULL, change);
node->set_status (exploded_node::STATUS_MERGER);
continue; continue;
} }
else else
...@@ -2232,12 +2240,18 @@ exploded_graph::process_worklist () ...@@ -2232,12 +2240,18 @@ exploded_graph::process_worklist ()
if (merged_enode == node) if (merged_enode == node)
m_worklist.add_node (merged_enode); m_worklist.add_node (merged_enode);
else else
{
add_edge (node, merged_enode, NULL, change); add_edge (node, merged_enode, NULL, change);
node->set_status (exploded_node::STATUS_MERGER);
}
if (merged_enode == node_2) if (merged_enode == node_2)
m_worklist.add_node (merged_enode); m_worklist.add_node (merged_enode);
else else
{
add_edge (node_2, merged_enode, NULL, change); add_edge (node_2, merged_enode, NULL, change);
node_2->set_status (exploded_node::STATUS_MERGER);
}
continue; continue;
} }
...@@ -2320,6 +2334,8 @@ exploded_graph::process_node (exploded_node *node) ...@@ -2320,6 +2334,8 @@ exploded_graph::process_node (exploded_node *node)
logger * const logger = get_logger (); logger * const logger = get_logger ();
LOG_FUNC_1 (logger, "EN: %i", node->m_index); LOG_FUNC_1 (logger, "EN: %i", node->m_index);
node->set_status (exploded_node::STATUS_PROCESSED);
const program_point &point = node->get_point (); const program_point &point = node->get_point ();
/* Update cfun and input_location in case of an ICE: make it easier to /* Update cfun and input_location in case of an ICE: make it easier to
...@@ -3180,8 +3196,16 @@ exploded_graph::dump_exploded_nodes () const ...@@ -3180,8 +3196,16 @@ exploded_graph::dump_exploded_nodes () const
} }
/* Emit a warning at any call to "__analyzer_dump_exploded_nodes", /* Emit a warning at any call to "__analyzer_dump_exploded_nodes",
giving the number of exploded nodes for "before-stmt", and their giving the number of processed exploded nodes for "before-stmt",
IDs. */ and the IDs of processed and merger enodes.
We highlight the count of *processed* enodes since this is of most
interest in DejaGnu tests for ensuring that state merger has
happened.
We don't show the count of merger enodes, as this is more of an
implementation detail of the merging that we don't want to bake
into our expected DejaGnu messages. */
unsigned i; unsigned i;
exploded_node *enode; exploded_node *enode;
...@@ -3199,25 +3223,43 @@ exploded_graph::dump_exploded_nodes () const ...@@ -3199,25 +3223,43 @@ exploded_graph::dump_exploded_nodes () const
if (seen.contains (stmt)) if (seen.contains (stmt))
continue; continue;
auto_vec<exploded_node *> processed_enodes;
auto_vec<exploded_node *> merger_enodes;
/* This is O(N^2). */ /* This is O(N^2). */
unsigned j; unsigned j;
auto_vec<exploded_node *> enodes;
exploded_node *other_enode; exploded_node *other_enode;
FOR_EACH_VEC_ELT (m_nodes, j, other_enode) FOR_EACH_VEC_ELT (m_nodes, j, other_enode)
{ {
if (other_enode->get_point ().get_kind () != PK_BEFORE_STMT) if (other_enode->get_point ().get_kind () != PK_BEFORE_STMT)
continue; continue;
if (other_enode->get_stmt () == stmt) if (other_enode->get_stmt () == stmt)
enodes.safe_push (other_enode); switch (other_enode->get_status ())
{
default:
gcc_unreachable ();
case exploded_node::STATUS_PROCESSED:
processed_enodes.safe_push (other_enode);
break;
case exploded_node::STATUS_MERGER:
merger_enodes.safe_push (other_enode);
break;
}
} }
pretty_printer pp; pretty_printer pp;
print_enode_indices (&pp, enodes); pp_character (&pp, '[');
print_enode_indices (&pp, processed_enodes);
if (merger_enodes.length () > 0)
{
pp_string (&pp, "] merger(s): [");
print_enode_indices (&pp, merger_enodes);
}
pp_character (&pp, ']');
warning_n (stmt->location, 0, enodes.length (), warning_n (stmt->location, 0, processed_enodes.length (),
"%i exploded node: %s", "%i processed enode: %s",
"%i exploded nodes: %s", "%i processed enodes: %s",
enodes.length (), pp_formatted_text (&pp)); processed_enodes.length (), pp_formatted_text (&pp));
seen.add (stmt); seen.add (stmt);
/* If the argument is non-zero, then print all of the states /* If the argument is non-zero, then print all of the states
...@@ -3233,10 +3275,11 @@ exploded_graph::dump_exploded_nodes () const ...@@ -3233,10 +3275,11 @@ exploded_graph::dump_exploded_nodes () const
if (i_arg) if (i_arg)
{ {
exploded_node *other_enode; exploded_node *other_enode;
FOR_EACH_VEC_ELT (enodes, j, other_enode) FOR_EACH_VEC_ELT (processed_enodes, j, other_enode)
{ {
fprintf (stderr, "%i of %i: EN %i:\n", fprintf (stderr, "%i of %i: EN %i:\n",
j + 1, enodes.length (), other_enode->m_index); j + 1, processed_enodes.length (),
other_enode->m_index);
other_enode->dump_succs_and_preds (stderr); other_enode->dump_succs_and_preds (stderr);
/* Dump state. */ /* Dump state. */
other_enode->get_state ().dump (m_ext_state, false); other_enode->get_state ().dump (m_ext_state, false);
......
...@@ -151,9 +151,26 @@ struct eg_traits ...@@ -151,9 +151,26 @@ struct eg_traits
class exploded_node : public dnode<eg_traits> class exploded_node : public dnode<eg_traits>
{ {
public: public:
/* Has this enode had exploded_graph::process_node called on it?
This allows us to distinguish enodes that were merged during
worklist-handling, and thus never had process_node called on them
(in favor of processing the merged node). */
enum status
{
/* Node is in the worklist. */
STATUS_WORKLIST,
/* Node has had exploded_graph::process_node called on it. */
STATUS_PROCESSED,
/* Node was left unprocessed due to merger; it won't have had
exploded_graph::process_node called on it. */
STATUS_MERGER
};
exploded_node (point_and_state ps, exploded_node (point_and_state ps,
int index) int index)
: m_ps (ps), m_index (index) : m_ps (ps), m_status (STATUS_WORKLIST), m_index (index)
{ {
gcc_checking_assert (ps.get_state ().m_region_model->canonicalized_p ()); gcc_checking_assert (ps.get_state ().m_region_model->canonicalized_p ());
} }
...@@ -240,6 +257,13 @@ class exploded_node : public dnode<eg_traits> ...@@ -240,6 +257,13 @@ class exploded_node : public dnode<eg_traits>
void dump_succs_and_preds (FILE *outf) const; void dump_succs_and_preds (FILE *outf) const;
enum status get_status () const { return m_status; }
void set_status (enum status status)
{
gcc_assert (m_status == STATUS_WORKLIST);
m_status = status;
}
private: private:
DISABLE_COPY_AND_ASSIGN (exploded_node); DISABLE_COPY_AND_ASSIGN (exploded_node);
...@@ -249,6 +273,8 @@ private: ...@@ -249,6 +273,8 @@ private:
is immutable once the exploded_node has been created. */ is immutable once the exploded_node has been created. */
const point_and_state m_ps; const point_and_state m_ps;
enum status m_status;
public: public:
/* The index of this exploded_node. */ /* The index of this exploded_node. */
const int m_index; const int m_index;
......
...@@ -469,20 +469,28 @@ __analyzer_dump_path (); ...@@ -469,20 +469,28 @@ __analyzer_dump_path ();
will emit a placeholder ``note'' diagnostic with a path to that call site, will emit a placeholder ``note'' diagnostic with a path to that call site,
if the analyzer finds a feasible path to it. if the analyzer finds a feasible path to it.
The builtin @code{__analyzer_dump_exploded_nodes} will dump information The builtin @code{__analyzer_dump_exploded_nodes} will emit a warning
after analysis on all of the exploded nodes at that program point: after analysis containing information on all of the exploded nodes at that
program point:
@smallexample @smallexample
__analyzer_dump_exploded_nodes (0); __analyzer_dump_exploded_nodes (0);
@end smallexample @end smallexample
will dump just the number of nodes, and their IDs. will output the number of ``processed'' nodes, and the IDs of
both ``processed'' and ``merger'' nodes, such as:
@smallexample
warning: 2 processed enodes: [EN: 56, EN: 58] merger(s): [EN: 54-55, EN: 57, EN: 59]
@end smallexample
With a non-zero argument
@smallexample @smallexample
__analyzer_dump_exploded_nodes (1); __analyzer_dump_exploded_nodes (1);
@end smallexample @end smallexample
will also dump all of the states within those nodes. it will also dump all of the states within the ``processed'' nodes.
@smallexample @smallexample
__analyzer_dump_region_model (); __analyzer_dump_region_model ();
......
2020-02-05 David Malcolm <dmalcolm@redhat.com>
* gcc.dg/analyzer/data-model-1.c: Update for changed output to
__analyzer_dump_exploded_nodes, dropping redundant call at merger.
* gcc.dg/analyzer/data-model-7.c: Likewise.
* gcc.dg/analyzer/loop-2.c: Update for changed output format.
* gcc.dg/analyzer/loop-2a.c: Likewise.
* gcc.dg/analyzer/loop-4.c: Likewise.
* gcc.dg/analyzer/loop.c: Likewise.
* gcc.dg/analyzer/malloc-paths-10.c: Likewise; drop redundant
call at merger.
* gcc.dg/analyzer/malloc-vs-local-1a.c: Likewise.
* gcc.dg/analyzer/malloc-vs-local-1b.c: Likewise.
* gcc.dg/analyzer/malloc-vs-local-2.c: Likewise.
* gcc.dg/analyzer/malloc-vs-local-3.c: Likewise.
* gcc.dg/analyzer/paths-1.c: Likewise.
* gcc.dg/analyzer/paths-1a.c: Likewise.
* gcc.dg/analyzer/paths-2.c: Likewise.
* gcc.dg/analyzer/paths-3.c: Likewise.
* gcc.dg/analyzer/paths-4.c: Update for changed output format.
* gcc.dg/analyzer/paths-5.c: Likewise.
* gcc.dg/analyzer/paths-6.c: Likewise; drop redundant calls
at merger.
* gcc.dg/analyzer/paths-7.c: Likewise.
* gcc.dg/analyzer/torture/conditionals-2.c: Update for changed
output format.
* gcc.dg/analyzer/zlib-1.c: Likewise; drop redundant calls.
* gcc.dg/analyzer/zlib-5.c: Update for changed output format.
2020-02-05 Jakub Jelinek <jakub@redhat.com> 2020-02-05 Jakub Jelinek <jakub@redhat.com>
PR target/92190 PR target/92190
......
...@@ -895,8 +895,7 @@ int test_40 (int flag) ...@@ -895,8 +895,7 @@ int test_40 (int flag)
i = 17; i = 17;
/* With state-merging, we lose the relationship between 'flag' and 'i'. */ /* With state-merging, we lose the relationship between 'flag' and 'i'. */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
if (flag) if (flag)
__analyzer_eval (i == 43); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (i == 43); /* { dg-warning "UNKNOWN" } */
......
...@@ -10,8 +10,7 @@ int test_40 (int flag) ...@@ -10,8 +10,7 @@ int test_40 (int flag)
i = 17; i = 17;
/* Without state-merging, we retain the relationship between 'flag' and 'i'. */ /* Without state-merging, we retain the relationship between 'flag' and 'i'. */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
if (flag) if (flag)
__analyzer_eval (i == 43); /* { dg-warning "TRUE" } */ __analyzer_eval (i == 43); /* { dg-warning "TRUE" } */
......
...@@ -10,14 +10,14 @@ void test(void) ...@@ -10,14 +10,14 @@ void test(void)
{ {
struct s s; struct s s;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
for (s.i=0; s.i<256; s.i++) { for (s.i=0; s.i<256; s.i++) {
__analyzer_eval (s.i < 256); /* { dg-warning "TRUE" } */ __analyzer_eval (s.i < 256); /* { dg-warning "TRUE" } */
/* (should report TRUE twice). */ /* (should report TRUE twice). */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
//__analyzer_eval (s.i == 0); /* { d-todo-g-warning "UNKNOWN" "" { xfail *-*-* } } */ //__analyzer_eval (s.i == 0); /* { d-todo-g-warning "UNKNOWN" "" { xfail *-*-* } } */
/* { d-todo-g-warning "TRUE" "" { target *-*-* } .-1 } */ /* { d-todo-g-warning "TRUE" "" { target *-*-* } .-1 } */
...@@ -33,5 +33,5 @@ void test(void) ...@@ -33,5 +33,5 @@ void test(void)
/* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
/* TODO(xfail^^^): ideally it should figure out i == 256 at exit. */ /* TODO(xfail^^^): ideally it should figure out i == 256 at exit. */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
} }
...@@ -10,7 +10,7 @@ void test(void) ...@@ -10,7 +10,7 @@ void test(void)
{ {
union u u; union u u;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
for (u.i=0; u.i<256; u.i++) { for (u.i=0; u.i<256; u.i++) {
...@@ -19,7 +19,7 @@ void test(void) ...@@ -19,7 +19,7 @@ void test(void)
/* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-2 } */ /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-2 } */
/* (should report TRUE twice). */ /* (should report TRUE twice). */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
//__analyzer_eval (u.i == 0); /* { d-todo-g-warning "UNKNOWN" "" { xfail *-*-* } } */ //__analyzer_eval (u.i == 0); /* { d-todo-g-warning "UNKNOWN" "" { xfail *-*-* } } */
/* { d-todo-g-warning "TRUE" "" { target *-*-* } .-1 } */ /* { d-todo-g-warning "TRUE" "" { target *-*-* } .-1 } */
...@@ -36,5 +36,5 @@ void test(void) ...@@ -36,5 +36,5 @@ void test(void)
/* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
/* TODO(xfail^^^): ideally it should figure out i == 256 at exit. */ /* TODO(xfail^^^): ideally it should figure out i == 256 at exit. */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
} }
...@@ -9,7 +9,7 @@ void test(void) ...@@ -9,7 +9,7 @@ void test(void)
{ {
int i, j, k; int i, j, k;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
for (i=0; i<256; i++) { for (i=0; i<256; i++) {
...@@ -25,7 +25,7 @@ void test(void) ...@@ -25,7 +25,7 @@ void test(void)
__analyzer_eval (j < 256); /* { dg-warning "TRUE" } */ __analyzer_eval (j < 256); /* { dg-warning "TRUE" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
for (k=0; k<256; k++) { for (k=0; k<256; k++) {
...@@ -34,10 +34,10 @@ void test(void) ...@@ -34,10 +34,10 @@ void test(void)
__analyzer_eval (k < 256); /* { dg-warning "TRUE" } */ __analyzer_eval (k < 256); /* { dg-warning "TRUE" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "4 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "4 processed enodes" } */
} }
} }
} }
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
} }
...@@ -6,7 +6,7 @@ void test(void) ...@@ -6,7 +6,7 @@ void test(void)
{ {
int i; int i;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
for (i=0; i<256; i++) { for (i=0; i<256; i++) {
__analyzer_eval (i < 256); /* { dg-warning "TRUE" } */ __analyzer_eval (i < 256); /* { dg-warning "TRUE" } */
...@@ -22,7 +22,7 @@ void test(void) ...@@ -22,7 +22,7 @@ void test(void)
/* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-2 } */ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-2 } */
/* TODO(xfail^^^): ideally we ought to figure out i >= 0 for all iterations. */ /* TODO(xfail^^^): ideally we ought to figure out i >= 0 for all iterations. */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
} }
__analyzer_eval (i >= 256); /* { dg-warning "TRUE" } */ __analyzer_eval (i >= 256); /* { dg-warning "TRUE" } */
...@@ -31,5 +31,5 @@ void test(void) ...@@ -31,5 +31,5 @@ void test(void)
/* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
/* TODO(xfail^^^): it only figures out i >= 256, rather than i == 256. */ /* TODO(xfail^^^): it only figures out i >= 256, rather than i == 256. */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
} }
...@@ -10,8 +10,7 @@ int test (int flag) ...@@ -10,8 +10,7 @@ int test (int flag)
other_flag = 0; other_flag = 0;
/* With state-merging, we lose the relationship between 'flag' and 'other_flag'. */ /* With state-merging, we lose the relationship between 'flag' and 'other_flag'. */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
if (other_flag) if (other_flag)
__analyzer_eval (flag); /* { dg-warning "UNKNOWN" } */ __analyzer_eval (flag); /* { dg-warning "UNKNOWN" } */
......
...@@ -44,14 +44,13 @@ int test_repeated_predicate_1 (int n) ...@@ -44,14 +44,13 @@ int test_repeated_predicate_1 (int n)
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
result = do_stuff (ptr, n); result = do_stuff (ptr, n);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
// FIXME: why 3 here? // FIXME: why 3 here?
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
// FIXME: why 3 here? // FIXME: why 3 here?
if (n > 10) if (n > 10)
...@@ -73,11 +72,11 @@ int test_repeated_predicate_2 (int n) ...@@ -73,11 +72,11 @@ int test_repeated_predicate_2 (int n)
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
result = do_stuff_2 (ptr, n); result = do_stuff_2 (ptr, n);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
if (n > 10) if (n > 10)
free (ptr); /* { dg-bogus "not on the heap" } */ free (ptr); /* { dg-bogus "not on the heap" } */
...@@ -102,11 +101,11 @@ int test_explicit_flag (int n) ...@@ -102,11 +101,11 @@ int test_explicit_flag (int n)
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
result = do_stuff (ptr, n); result = do_stuff (ptr, n);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
// FIXME: why 3 here? // FIXME: why 3 here?
if (need_to_free) if (need_to_free)
...@@ -128,11 +127,11 @@ int test_pointer_comparison (int n) ...@@ -128,11 +127,11 @@ int test_pointer_comparison (int n)
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
result = do_stuff (ptr, n); result = do_stuff (ptr, n);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
// FIXME: why 3 here? // FIXME: why 3 here?
if (ptr != buf) if (ptr != buf)
...@@ -159,19 +158,18 @@ int test_initial_flag (int n) ...@@ -159,19 +158,18 @@ int test_initial_flag (int n)
/* Due to state-merging, we lose the relationship between 'n > 10' /* Due to state-merging, we lose the relationship between 'n > 10'
and 'on_heap' here; we have to rely on feasibility-checking and 'on_heap' here; we have to rely on feasibility-checking
in the diagnostic_manager to reject the false warnings. */ in the diagnostic_manager to reject the false warnings. */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
if (on_heap) if (on_heap)
ptr = (int *)malloc (sizeof (int) * n); ptr = (int *)malloc (sizeof (int) * n);
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
result = do_stuff (ptr, n); result = do_stuff (ptr, n);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "5 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "5 processed enodes" } */
// FIXME: why 5 here? // FIXME: why 5 here?
if (n > 10) if (n > 10)
......
...@@ -44,13 +44,11 @@ int test_repeated_predicate_1 (int n) ...@@ -44,13 +44,11 @@ int test_repeated_predicate_1 (int n)
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
result = do_stuff (ptr, n); result = do_stuff (ptr, n);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
if (n > 10) if (n > 10)
free (ptr); /* { dg-bogus "not on the heap" } */ free (ptr); /* { dg-bogus "not on the heap" } */
...@@ -71,11 +69,11 @@ int test_repeated_predicate_2 (int n) ...@@ -71,11 +69,11 @@ int test_repeated_predicate_2 (int n)
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
result = do_stuff_2 (ptr, n); result = do_stuff_2 (ptr, n);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
if (n > 10) if (n > 10)
free (ptr); /* { dg-bogus "not on the heap" } */ free (ptr); /* { dg-bogus "not on the heap" } */
...@@ -100,11 +98,11 @@ int test_explicit_flag (int n) ...@@ -100,11 +98,11 @@ int test_explicit_flag (int n)
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
result = do_stuff (ptr, n); result = do_stuff (ptr, n);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
if (need_to_free) if (need_to_free)
free (ptr); /* { dg-bogus "not on the heap" } */ free (ptr); /* { dg-bogus "not on the heap" } */
...@@ -125,11 +123,11 @@ int test_pointer_comparison (int n) ...@@ -125,11 +123,11 @@ int test_pointer_comparison (int n)
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
result = do_stuff (ptr, n); result = do_stuff (ptr, n);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
if (ptr != buf) if (ptr != buf)
free (ptr); /* { dg-bogus "not on the heap" } */ free (ptr); /* { dg-bogus "not on the heap" } */
...@@ -155,19 +153,18 @@ int test_initial_flag (int n) ...@@ -155,19 +153,18 @@ int test_initial_flag (int n)
/* Due to state-merging, we lose the relationship between 'n > 10' /* Due to state-merging, we lose the relationship between 'n > 10'
and 'on_heap' here; we have to rely on feasibility-checking and 'on_heap' here; we have to rely on feasibility-checking
in the diagnostic_manager to reject the false warnings. */ in the diagnostic_manager to reject the false warnings. */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
if (on_heap) if (on_heap)
ptr = (int *)malloc (sizeof (int) * n); ptr = (int *)malloc (sizeof (int) * n);
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
result = do_stuff (ptr, n); result = do_stuff (ptr, n);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
if (n > 10) if (n > 10)
free (ptr); /* { dg-bogus "not on the heap" } */ free (ptr); /* { dg-bogus "not on the heap" } */
......
...@@ -24,8 +24,7 @@ int test_repeated_predicate_1 (int n) ...@@ -24,8 +24,7 @@ int test_repeated_predicate_1 (int n)
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
{ {
int *p = ptr; int *p = ptr;
...@@ -38,8 +37,7 @@ int test_repeated_predicate_1 (int n) ...@@ -38,8 +37,7 @@ int test_repeated_predicate_1 (int n)
result = sum; result = sum;
} }
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */
if (n > 10) if (n > 10)
free (ptr); /* { dg-bogus "not on the heap" } */ free (ptr); /* { dg-bogus "not on the heap" } */
...@@ -60,8 +58,7 @@ int test_repeated_predicate_1a (int n) ...@@ -60,8 +58,7 @@ int test_repeated_predicate_1a (int n)
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
{ {
int *p = ptr; int *p = ptr;
...@@ -72,8 +69,7 @@ int test_repeated_predicate_1a (int n) ...@@ -72,8 +69,7 @@ int test_repeated_predicate_1a (int n)
result = sum; result = sum;
} }
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */
if (n > 10) if (n > 10)
free (ptr); /* { dg-bogus "not on the heap" } */ free (ptr); /* { dg-bogus "not on the heap" } */
...@@ -94,11 +90,11 @@ int test_repeated_predicate_2 (int n) ...@@ -94,11 +90,11 @@ int test_repeated_predicate_2 (int n)
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
result = do_stuff_2 (ptr, n); result = do_stuff_2 (ptr, n);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
if (n > 10) if (n > 10)
free (ptr); /* { dg-bogus "not on the heap" } */ free (ptr); /* { dg-bogus "not on the heap" } */
...@@ -123,7 +119,7 @@ int test_explicit_flag (int n) ...@@ -123,7 +119,7 @@ int test_explicit_flag (int n)
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
{ {
int *p = ptr; int *p = ptr;
...@@ -136,7 +132,7 @@ int test_explicit_flag (int n) ...@@ -136,7 +132,7 @@ int test_explicit_flag (int n)
result = sum; result = sum;
} }
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
if (need_to_free) if (need_to_free)
free (ptr); /* { dg-bogus "not on the heap" } */ free (ptr); /* { dg-bogus "not on the heap" } */
...@@ -157,7 +153,7 @@ int test_pointer_comparison (int n) ...@@ -157,7 +153,7 @@ int test_pointer_comparison (int n)
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
{ {
int *p = ptr; int *p = ptr;
...@@ -170,7 +166,7 @@ int test_pointer_comparison (int n) ...@@ -170,7 +166,7 @@ int test_pointer_comparison (int n)
result = sum; result = sum;
} }
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
if (ptr != buf) if (ptr != buf)
free (ptr); /* { dg-bogus "not on the heap" } */ free (ptr); /* { dg-bogus "not on the heap" } */
......
...@@ -23,8 +23,7 @@ int test_1 (int n) ...@@ -23,8 +23,7 @@ int test_1 (int n)
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
{ {
int *p = ptr; int *p = ptr;
...@@ -37,7 +36,7 @@ int test_1 (int n) ...@@ -37,7 +36,7 @@ int test_1 (int n)
result = sum; result = sum;
} }
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
return result; /* { dg-message "leak of 'p'" } */ return result; /* { dg-message "leak of 'p'" } */
/* FIXME: should this be 'ptr'? */ /* FIXME: should this be 'ptr'? */
...@@ -56,11 +55,11 @@ int test_2 (int n) ...@@ -56,11 +55,11 @@ int test_2 (int n)
else else
ptr = buf; ptr = buf;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
result = do_stuff_2 (ptr, n); result = do_stuff_2 (ptr, n);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
return result; /* { dg-message "leak of 'ptr'" } */ return result; /* { dg-message "leak of 'ptr'" } */
} }
...@@ -13,6 +13,5 @@ void test (struct foo *pf) ...@@ -13,6 +13,5 @@ void test (struct foo *pf)
bar (0); bar (0);
else else
bar (1); bar (1);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
} }
...@@ -13,6 +13,5 @@ void test (union foo *pf) ...@@ -13,6 +13,5 @@ void test (union foo *pf)
bar (0); bar (0);
else else
bar (1); bar (1);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
} }
...@@ -6,9 +6,7 @@ int test (int a) ...@@ -6,9 +6,7 @@ int test (int a)
return (-2); return (-2);
} }
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
return 0; return 0;
} }
...@@ -19,9 +17,7 @@ int test_2 (int a) ...@@ -19,9 +17,7 @@ int test_2 (int a)
return (-2); return (-2);
} }
__analyzer_dump_exploded_nodes (0); /* { dg-warning "4 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
return 0; return 0;
} }
...@@ -13,13 +13,12 @@ int test_1 (int a, int b) ...@@ -13,13 +13,12 @@ int test_1 (int a, int b)
else else
p = malloc (32); p = malloc (32);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "4 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
if (a > 5) if (a > 5)
{ {
free (p); free (p);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
} }
return 0; /* { dg-bogus "leak" } */ return 0; /* { dg-bogus "leak" } */
...@@ -35,13 +34,12 @@ int test_2 (int a, int b) ...@@ -35,13 +34,12 @@ int test_2 (int a, int b)
else else
p = malloc (32); p = malloc (32);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "4 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */
if (a > 6) /* different condition */ if (a > 6) /* different condition */
{ {
free (p); free (p);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
} }
return 0; /* { dg-warning "leak of 'p'" } */ return 0; /* { dg-warning "leak of 'p'" } */
......
...@@ -10,41 +10,43 @@ extern void do_stuff (struct state *, int); ...@@ -10,41 +10,43 @@ extern void do_stuff (struct state *, int);
int test_1 (struct state *s) int test_1 (struct state *s)
{ {
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
while (1) while (1)
{ {
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
/* TODO: why does the above need an extra stmt to merge state? */
do_stuff (s, s->mode); do_stuff (s, s->mode);
} }
} }
int test_2 (struct state *s) int test_2 (struct state *s)
{ {
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
while (1) while (1)
{ {
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
/* TODO: why does the above need an extra stmt to merge state? */
switch (s->mode) switch (s->mode)
{ {
case 0: case 0:
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
do_stuff (s, 0); do_stuff (s, 0);
break; break;
case 1: case 1:
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
do_stuff (s, 17); do_stuff (s, 17);
break; break;
case 2: case 2:
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
do_stuff (s, 5); do_stuff (s, 5);
break; break;
case 3: case 3:
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
return 42; return 42;
case 4: case 4:
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
return -3; return -3;
} }
} }
......
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
void test (int *p, int n) void test (int *p, int n)
{ {
int i; int i;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
p[i] = i; /* { dg-bogus "uninitialized" } */ p[i] = i; /* { dg-bogus "uninitialized" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
} }
} }
...@@ -19,9 +19,7 @@ void test_1 (int flag) ...@@ -19,9 +19,7 @@ void test_1 (int flag)
a = 3; a = 3;
} }
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
// FIXME: the above can vary between 2 and 3 exploded nodes
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
__analyzer_eval (a == 3); /* { dg-warning "TRUE" } */ __analyzer_eval (a == 3); /* { dg-warning "TRUE" } */
__analyzer_eval (b == 4); /* { dg-warning "TRUE" } */ __analyzer_eval (b == 4); /* { dg-warning "TRUE" } */
} }
...@@ -42,8 +40,7 @@ void test_2 (int flag) ...@@ -42,8 +40,7 @@ void test_2 (int flag)
f = 3; f = 3;
} }
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
__analyzer_eval (f == 3); /* { dg-warning "TRUE" } */ __analyzer_eval (f == 3); /* { dg-warning "TRUE" } */
__analyzer_eval (g == 4); /* { dg-warning "TRUE" } */ __analyzer_eval (g == 4); /* { dg-warning "TRUE" } */
} }
...@@ -92,8 +89,7 @@ void test_3 (int i) ...@@ -92,8 +89,7 @@ void test_3 (int i)
break; break;
} }
__analyzer_dump_exploded_nodes (0); /* { dg-warning "6 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enode" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded node" } */
__analyzer_eval (f == 3); /* { dg-warning "TRUE" } */ __analyzer_eval (f == 3); /* { dg-warning "TRUE" } */
__analyzer_eval (g == 4); /* { dg-warning "TRUE" } */ __analyzer_eval (g == 4); /* { dg-warning "TRUE" } */
__analyzer_eval (h == 5); /* { dg-warning "TRUE" } */ __analyzer_eval (h == 5); /* { dg-warning "TRUE" } */
...@@ -112,8 +108,7 @@ void test_4 (int flag) ...@@ -112,8 +108,7 @@ void test_4 (int flag)
q = malloc (256); q = malloc (256);
p = malloc (256); p = malloc (256);
} }
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
free (p); free (p);
free (q); free (q);
} }
...@@ -9,12 +9,12 @@ int test (int flag, void *ptr, int *p, int n) ...@@ -9,12 +9,12 @@ int test (int flag, void *ptr, int *p, int n)
int sum = 0; int sum = 0;
int i; int i;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
if (flag) if (flag)
free (ptr); free (ptr);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
p[i] = i; p[i] = i;
...@@ -22,7 +22,7 @@ int test (int flag, void *ptr, int *p, int n) ...@@ -22,7 +22,7 @@ int test (int flag, void *ptr, int *p, int n)
sum += foo (p[i]); /* { dg-bogus "uninitialized" } */ sum += foo (p[i]); /* { dg-bogus "uninitialized" } */
result = sum; result = sum;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
if (flag) if (flag)
free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */ free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */
...@@ -37,12 +37,12 @@ int test_2 (int flag, int *p, int n) ...@@ -37,12 +37,12 @@ int test_2 (int flag, int *p, int n)
void *ptr = malloc (16); void *ptr = malloc (16);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
if (flag) if (flag)
free (ptr); free (ptr);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
p[i] = i; p[i] = i;
...@@ -50,8 +50,7 @@ int test_2 (int flag, int *p, int n) ...@@ -50,8 +50,7 @@ int test_2 (int flag, int *p, int n)
sum += foo (p[i]); /* { dg-bogus "uninitialized" } */ sum += foo (p[i]); /* { dg-bogus "uninitialized" } */
result = sum; result = sum;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "5 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "5 processed enodes" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "5 exploded nodes" } */
// FIXME: why 5 here? // FIXME: why 5 here?
free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */ free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
static void __attribute__((noinline)) static void __attribute__((noinline))
test_1_callee (void *p, void *q) test_1_callee (void *p, void *q)
{ {
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_eval (p == Z_NULL); /* { dg-warning "FALSE" } */ __analyzer_eval (p == Z_NULL); /* { dg-warning "FALSE" } */
__analyzer_eval (p != Z_NULL); /* { dg-warning "TRUE" } */ __analyzer_eval (p != Z_NULL); /* { dg-warning "TRUE" } */
...@@ -27,7 +27,7 @@ void test_1 (void *p, void *q) ...@@ -27,7 +27,7 @@ void test_1 (void *p, void *q)
static void __attribute__((noinline)) static void __attribute__((noinline))
test_2_callee (void *p, void *q) test_2_callee (void *p, void *q)
{ {
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_eval (p == Z_NULL); /* { dg-warning "FALSE" } */ __analyzer_eval (p == Z_NULL); /* { dg-warning "FALSE" } */
__analyzer_eval (p != Z_NULL); /* { dg-warning "TRUE" } */ __analyzer_eval (p != Z_NULL); /* { dg-warning "TRUE" } */
......
...@@ -21,49 +21,44 @@ int deflateEnd(z_stream *strm) ...@@ -21,49 +21,44 @@ int deflateEnd(z_stream *strm)
{ {
int status; int status;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
if (strm == 0 || strm->state == 0) if (strm == 0 || strm->state == 0)
return (-2); return (-2);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
status = strm->state->status; status = strm->state->status;
if (status != 42 && status != 113 && status != 666) { if (status != 42 && status != 113 && status != 666) {
return (-2); return (-2);
} }
__analyzer_dump_exploded_nodes (0); /* { dg-warning "4 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
if (strm->state->pending_buf) if (strm->state->pending_buf)
(*(strm->zfree))(strm->opaque, (void *)(strm->state->pending_buf)); (*(strm->zfree))(strm->opaque, (void *)(strm->state->pending_buf));
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
if (strm->state->head) if (strm->state->head)
(*(strm->zfree))(strm->opaque, (void *)(strm->state->head)); (*(strm->zfree))(strm->opaque, (void *)(strm->state->head));
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
if (strm->state->prev) if (strm->state->prev)
(*(strm->zfree))(strm->opaque, (void *)(strm->state->prev)); (*(strm->zfree))(strm->opaque, (void *)(strm->state->prev));
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
if (strm->state->window) if (strm->state->window)
(*(strm->zfree))(strm->opaque, (void *)(strm->state->window)); (*(strm->zfree))(strm->opaque, (void *)(strm->state->window));
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 exploded nodes" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */
(*(strm->zfree))(strm->opaque, (void *)(strm->state)); (*(strm->zfree))(strm->opaque, (void *)(strm->state));
strm->state = 0; strm->state = 0;
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
return status == 113 ? (-3) : 0; return status == 113 ? (-3) : 0;
} }
...@@ -42,7 +42,7 @@ int main(int argc, char *argv[]) { ...@@ -42,7 +42,7 @@ int main(int argc, char *argv[]) {
if (compr == 0 || uncompr == 0) if (compr == 0 || uncompr == 0)
exit(1); exit(1);
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 exploded node" } */ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
test_compress(compr, comprLen, uncompr, uncomprLen); test_compress(compr, comprLen, uncompr, uncomprLen);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment