aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/engine.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/analyzer/engine.cc')
-rw-r--r--gcc/analyzer/engine.cc28
1 files changed, 24 insertions, 4 deletions
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 720fa21..573f9f6 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -135,6 +135,15 @@ impl_region_model_context::on_svalue_purge (svalue_id first_unused_sid,
return total;
}
+void
+impl_region_model_context::on_unknown_change (svalue_id sid)
+{
+ int sm_idx;
+ sm_state_map *smap;
+ FOR_EACH_VEC_ELT (m_new_state->m_checker_states, sm_idx, smap)
+ smap->on_unknown_change (sid);
+}
+
/* class setjmp_svalue : public svalue. */
/* Compare the fields of this setjmp_svalue with OTHER, returning true
@@ -876,7 +885,7 @@ exploded_node::dump (const extrinsic_state &ext_state) const
/* Return true if FNDECL has a gimple body. */
// TODO: is there a pre-canned way to do this?
-static bool
+bool
fndecl_has_gimple_body_p (tree fndecl)
{
if (fndecl == NULL_TREE)
@@ -935,6 +944,10 @@ exploded_node::on_stmt (exploded_graph &eg,
if (const greturn *return_ = dyn_cast <const greturn *> (stmt))
state->m_region_model->on_return (return_, &ctxt);
+ /* Track whether we have a gcall to a function that's not recognized by
+ anything, for which we don't have a function body, or for which we
+ don't know the fndecl. */
+ bool unknown_side_effects = false;
if (const gcall *call = dyn_cast <const gcall *> (stmt))
{
/* Debugging/test support. */
@@ -977,6 +990,11 @@ exploded_node::on_stmt (exploded_graph &eg,
/* TODO: is there a good cross-platform way to do this? */
raise (SIGINT);
}
+ else if (is_special_named_call_p (call, "__analyzer_dump_exploded_nodes",
+ 1))
+ {
+ /* This is handled elsewhere. */
+ }
else if (is_setjmp_call_p (stmt))
state->m_region_model->on_setjmp (call, this, &ctxt);
else if (is_longjmp_call_p (call))
@@ -985,7 +1003,7 @@ exploded_node::on_stmt (exploded_graph &eg,
return on_stmt_flags::terminate_path ();
}
else
- state->m_region_model->on_call_pre (call, &ctxt);
+ unknown_side_effects = state->m_region_model->on_call_pre (call, &ctxt);
}
bool any_sm_changes = false;
@@ -1001,7 +1019,9 @@ exploded_node::on_stmt (exploded_graph &eg,
change,
old_smap, new_smap);
/* Allow the state_machine to handle the stmt. */
- if (!sm.on_stmt (&ctxt, snode, stmt))
+ if (sm.on_stmt (&ctxt, snode, stmt))
+ unknown_side_effects = false;
+ else
{
/* For those stmts that were not handled by the state machine. */
if (const gcall *call = dyn_cast <const gcall *> (stmt))
@@ -1019,7 +1039,7 @@ exploded_node::on_stmt (exploded_graph &eg,
}
if (const gcall *call = dyn_cast <const gcall *> (stmt))
- state->m_region_model->on_call_post (call, &ctxt);
+ state->m_region_model->on_call_post (call, unknown_side_effects, &ctxt);
return on_stmt_flags (any_sm_changes);
}