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:
David Malcolm 2023-09-15 13:47:42 -04:00
parent 6319b5b2d4
commit 759a1a52ea
5 changed files with 71 additions and 44 deletions

View file

@ -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;

View file

@ -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. */

View file

@ -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);

View file

@ -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.

View file

@ -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));