analyzer: introduce pending_location
No functional change intended. gcc/analyzer/ChangeLog: * analyzer.h (struct pending_location): New forward decl. * diagnostic-manager.cc (saved_diagnostic::saved_diagnostic): Replace params "enode", "snode", "stmt", and "stmt_finder" with "ploc". (diagnostic_manager::add_diagnostic): Likewise for both overloads. * diagnostic-manager.h (saved_diagnostic::saved_diagnostic): Likewise. (struct pending_location): New. (diagnostic_manager::add_diagnostic): Replace params "enode", "snode", "stmt", and "stmt_finder" with "ploc". * engine.cc (impl_region_model_context::warn): Update call to add_diagnostic for above change. (impl_sm_context::warn): Likewise. (impl_region_model_context::on_state_leak): Likewise. * infinite-recursion.cc (exploded_graph::detect_infinite_recursion): Likewise. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
This commit is contained in:
parent
6319b5b2d4
commit
759a1a52ea
5 changed files with 71 additions and 44 deletions
|
@ -90,6 +90,7 @@ class reachable_regions;
|
|||
class bounded_ranges;
|
||||
class bounded_ranges_manager;
|
||||
|
||||
struct pending_location;
|
||||
class pending_diagnostic;
|
||||
class pending_note;
|
||||
struct event_loc_info;
|
||||
|
|
|
@ -664,22 +664,20 @@ epath_finder::dump_feasible_path (const exploded_node *target_enode,
|
|||
|
||||
/* class saved_diagnostic. */
|
||||
|
||||
/* saved_diagnostic's ctor.
|
||||
Take ownership of D and STMT_FINDER. */
|
||||
/* saved_diagnostic's ctor. */
|
||||
|
||||
saved_diagnostic::saved_diagnostic (const state_machine *sm,
|
||||
const exploded_node *enode,
|
||||
const supernode *snode, const gimple *stmt,
|
||||
const stmt_finder *stmt_finder,
|
||||
const pending_location &ploc,
|
||||
tree var,
|
||||
const svalue *sval,
|
||||
state_machine::state_t state,
|
||||
std::unique_ptr<pending_diagnostic> d,
|
||||
unsigned idx)
|
||||
: m_sm (sm), m_enode (enode), m_snode (snode), m_stmt (stmt),
|
||||
/* stmt_finder could be on-stack; we want our own copy that can
|
||||
outlive that. */
|
||||
m_stmt_finder (stmt_finder ? stmt_finder->clone () : NULL),
|
||||
: m_sm (sm), m_enode (ploc.m_enode), m_snode (ploc.m_snode),
|
||||
m_stmt (ploc.m_stmt),
|
||||
/* stmt_finder could be on-stack; we want our own copy that can
|
||||
outlive that. */
|
||||
m_stmt_finder (ploc.m_finder ? ploc.m_finder->clone () : NULL),
|
||||
m_var (var), m_sval (sval), m_state (state),
|
||||
m_d (std::move (d)), m_trailing_eedge (NULL),
|
||||
m_idx (idx),
|
||||
|
@ -1102,9 +1100,7 @@ diagnostic_manager::diagnostic_manager (logger *logger, engine *eng,
|
|||
|
||||
bool
|
||||
diagnostic_manager::add_diagnostic (const state_machine *sm,
|
||||
exploded_node *enode,
|
||||
const supernode *snode, const gimple *stmt,
|
||||
const stmt_finder *finder,
|
||||
const pending_location &ploc,
|
||||
tree var,
|
||||
const svalue *sval,
|
||||
state_machine::state_t state,
|
||||
|
@ -1114,15 +1110,16 @@ diagnostic_manager::add_diagnostic (const state_machine *sm,
|
|||
|
||||
/* We must have an enode in order to be able to look for paths
|
||||
through the exploded_graph to the diagnostic. */
|
||||
gcc_assert (enode);
|
||||
gcc_assert (ploc.m_enode);
|
||||
|
||||
/* If this warning is ultimately going to be rejected by a -Wno-analyzer-*
|
||||
flag, reject it now.
|
||||
We can only do this for diagnostics where we already know the stmt,
|
||||
and thus can determine the emission location. */
|
||||
if (stmt)
|
||||
if (ploc.m_stmt)
|
||||
{
|
||||
location_t loc = get_emission_location (stmt, snode->m_fun, *d);
|
||||
location_t loc
|
||||
= get_emission_location (ploc.m_stmt, ploc.m_snode->m_fun, *d);
|
||||
int option = d->get_controlling_option ();
|
||||
if (!warning_enabled_at (loc, option))
|
||||
{
|
||||
|
@ -1135,14 +1132,14 @@ diagnostic_manager::add_diagnostic (const state_machine *sm,
|
|||
}
|
||||
|
||||
saved_diagnostic *sd
|
||||
= new saved_diagnostic (sm, enode, snode, stmt, finder, var, sval,
|
||||
state, std::move (d), m_saved_diagnostics.length ());
|
||||
= new saved_diagnostic (sm, ploc, var, sval, state, std::move (d),
|
||||
m_saved_diagnostics.length ());
|
||||
m_saved_diagnostics.safe_push (sd);
|
||||
enode->add_diagnostic (sd);
|
||||
ploc.m_enode->add_diagnostic (sd);
|
||||
if (get_logger ())
|
||||
log ("adding saved diagnostic %i at SN %i to EN %i: %qs",
|
||||
sd->get_index (),
|
||||
snode->m_index, enode->m_index, sd->m_d->get_kind ());
|
||||
ploc.m_snode->m_index, ploc.m_enode->m_index, sd->m_d->get_kind ());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1151,14 +1148,11 @@ diagnostic_manager::add_diagnostic (const state_machine *sm,
|
|||
Take ownership of D (or delete it). */
|
||||
|
||||
bool
|
||||
diagnostic_manager::add_diagnostic (exploded_node *enode,
|
||||
const supernode *snode, const gimple *stmt,
|
||||
const stmt_finder *finder,
|
||||
diagnostic_manager::add_diagnostic (const pending_location &ploc,
|
||||
std::unique_ptr<pending_diagnostic> d)
|
||||
{
|
||||
gcc_assert (enode);
|
||||
return add_diagnostic (NULL, enode, snode, stmt, finder, NULL_TREE,
|
||||
NULL, 0, std::move (d));
|
||||
gcc_assert (ploc.m_enode);
|
||||
return add_diagnostic (NULL, ploc, NULL_TREE, NULL, 0, std::move (d));
|
||||
}
|
||||
|
||||
/* Add PN to the most recent saved_diagnostic. */
|
||||
|
|
|
@ -31,9 +31,7 @@ class saved_diagnostic
|
|||
{
|
||||
public:
|
||||
saved_diagnostic (const state_machine *sm,
|
||||
const exploded_node *enode,
|
||||
const supernode *snode, const gimple *stmt,
|
||||
const stmt_finder *stmt_finder,
|
||||
const pending_location &ploc,
|
||||
tree var, const svalue *sval,
|
||||
state_machine::state_t state,
|
||||
std::unique_ptr<pending_diagnostic> d,
|
||||
|
@ -100,6 +98,30 @@ private:
|
|||
|
||||
class path_builder;
|
||||
|
||||
/* A bundle of information capturing where a pending_diagnostic should
|
||||
be emitted. */
|
||||
|
||||
struct pending_location
|
||||
{
|
||||
public:
|
||||
pending_location (exploded_node *enode,
|
||||
const supernode *snode,
|
||||
const gimple *stmt,
|
||||
const stmt_finder *finder)
|
||||
: m_enode (enode),
|
||||
m_snode (snode),
|
||||
m_stmt (stmt),
|
||||
m_finder (finder)
|
||||
{
|
||||
gcc_assert (m_stmt || m_finder);
|
||||
}
|
||||
|
||||
exploded_node *m_enode;
|
||||
const supernode *m_snode;
|
||||
const gimple *m_stmt;
|
||||
const stmt_finder *m_finder;
|
||||
};
|
||||
|
||||
/* A class with responsibility for saving pending diagnostics, so that
|
||||
they can be emitted after the exploded_graph is complete.
|
||||
This lets us de-duplicate diagnostics, and find the shortest path
|
||||
|
@ -119,17 +141,13 @@ public:
|
|||
json::object *to_json () const;
|
||||
|
||||
bool add_diagnostic (const state_machine *sm,
|
||||
exploded_node *enode,
|
||||
const supernode *snode, const gimple *stmt,
|
||||
const stmt_finder *finder,
|
||||
const pending_location &ploc,
|
||||
tree var,
|
||||
const svalue *sval,
|
||||
state_machine::state_t state,
|
||||
std::unique_ptr<pending_diagnostic> d);
|
||||
|
||||
bool add_diagnostic (exploded_node *enode,
|
||||
const supernode *snode, const gimple *stmt,
|
||||
const stmt_finder *finder,
|
||||
bool add_diagnostic (const pending_location &ploc,
|
||||
std::unique_ptr<pending_diagnostic> d);
|
||||
|
||||
void add_note (std::unique_ptr<pending_note> pn);
|
||||
|
|
|
@ -129,9 +129,12 @@ impl_region_model_context::warn (std::unique_ptr<pending_diagnostic> d,
|
|||
if (m_eg)
|
||||
{
|
||||
bool terminate_path = d->terminate_path_p ();
|
||||
if (m_eg->get_diagnostic_manager ().add_diagnostic
|
||||
(m_enode_for_diag, m_enode_for_diag->get_supernode (),
|
||||
m_stmt, curr_stmt_finder, std::move (d)))
|
||||
pending_location ploc (m_enode_for_diag,
|
||||
m_enode_for_diag->get_supernode (),
|
||||
m_stmt,
|
||||
curr_stmt_finder);
|
||||
if (m_eg->get_diagnostic_manager ().add_diagnostic (ploc,
|
||||
std::move (d)))
|
||||
{
|
||||
if (m_path_ctxt
|
||||
&& terminate_path
|
||||
|
@ -398,8 +401,9 @@ public:
|
|||
? m_old_smap->get_state (var_old_sval, m_eg.get_ext_state ())
|
||||
: m_old_smap->get_global_state ());
|
||||
bool terminate_path = d->terminate_path_p ();
|
||||
pending_location ploc (m_enode_for_diag, snode, stmt, m_stmt_finder);
|
||||
m_eg.get_diagnostic_manager ().add_diagnostic
|
||||
(&m_sm, m_enode_for_diag, snode, stmt, m_stmt_finder,
|
||||
(&m_sm, ploc,
|
||||
var, var_old_sval, current, std::move (d));
|
||||
if (m_path_ctxt
|
||||
&& terminate_path
|
||||
|
@ -418,8 +422,9 @@ public:
|
|||
? m_old_smap->get_state (sval, m_eg.get_ext_state ())
|
||||
: m_old_smap->get_global_state ());
|
||||
bool terminate_path = d->terminate_path_p ();
|
||||
pending_location ploc (m_enode_for_diag, snode, stmt, m_stmt_finder);
|
||||
m_eg.get_diagnostic_manager ().add_diagnostic
|
||||
(&m_sm, m_enode_for_diag, snode, stmt, m_stmt_finder,
|
||||
(&m_sm, ploc,
|
||||
NULL_TREE, sval, current, std::move (d));
|
||||
if (m_path_ctxt
|
||||
&& terminate_path
|
||||
|
@ -898,10 +903,15 @@ impl_region_model_context::on_state_leak (const state_machine &sm,
|
|||
tree leaked_tree_for_diag = fixup_tree_for_diagnostic (leaked_tree);
|
||||
std::unique_ptr<pending_diagnostic> pd = sm.on_leak (leaked_tree_for_diag);
|
||||
if (pd)
|
||||
m_eg->get_diagnostic_manager ().add_diagnostic
|
||||
(&sm, m_enode_for_diag, m_enode_for_diag->get_supernode (),
|
||||
m_stmt, &stmt_finder,
|
||||
leaked_tree_for_diag, sval, state, std::move (pd));
|
||||
{
|
||||
pending_location ploc (m_enode_for_diag,
|
||||
m_enode_for_diag->get_supernode (),
|
||||
m_stmt,
|
||||
&stmt_finder);
|
||||
m_eg->get_diagnostic_manager ().add_diagnostic
|
||||
(&sm, ploc,
|
||||
leaked_tree_for_diag, sval, state, std::move (pd));
|
||||
}
|
||||
}
|
||||
|
||||
/* Implementation of region_model_context::on_condition vfunc.
|
||||
|
|
|
@ -625,8 +625,12 @@ exploded_graph::detect_infinite_recursion (exploded_node *enode)
|
|||
const supernode *caller_snode = call_string.get_top_of_stack ().m_caller;
|
||||
const supernode *snode = enode->get_supernode ();
|
||||
gcc_assert (caller_snode->m_returning_call);
|
||||
pending_location ploc (enode,
|
||||
snode,
|
||||
caller_snode->m_returning_call,
|
||||
nullptr);
|
||||
get_diagnostic_manager ().add_diagnostic
|
||||
(enode, snode, caller_snode->m_returning_call, NULL,
|
||||
(ploc,
|
||||
make_unique<infinite_recursion_diagnostic> (prev_entry_enode,
|
||||
enode,
|
||||
fndecl));
|
||||
|
|
Loading…
Add table
Reference in a new issue