/* Classes for saving, deduplicating, and emitting analyzer diagnostics.
- Copyright (C) 2019-2020 Free Software Foundation, Inc.
+ Copyright (C) 2019-2023 Free Software Foundation, Inc.
Contributed by David Malcolm <dmalcolm@redhat.com>.
This file is part of GCC.
#ifndef GCC_ANALYZER_DIAGNOSTIC_MANAGER_H
#define GCC_ANALYZER_DIAGNOSTIC_MANAGER_H
+namespace ana {
+
+class epath_finder;
+
/* A to-be-emitted diagnostic stored within diagnostic_manager. */
class saved_diagnostic
saved_diagnostic (const state_machine *sm,
const exploded_node *enode,
const supernode *snode, const gimple *stmt,
- stmt_finder *stmt_finder,
- tree var, state_machine::state_t state,
- pending_diagnostic *d);
- ~saved_diagnostic ();
+ const stmt_finder *stmt_finder,
+ tree var, const svalue *sval,
+ state_machine::state_t state,
+ std::unique_ptr<pending_diagnostic> d,
+ unsigned idx);
+
+ bool operator== (const saved_diagnostic &other) const;
+
+ void add_note (std::unique_ptr<pending_note> pn);
- bool operator== (const saved_diagnostic &other) const
+ json::object *to_json () const;
+
+ void dump_dot_id (pretty_printer *pp) const;
+ void dump_as_dot_node (pretty_printer *pp) const;
+
+ const feasibility_problem *get_feasibility_problem () const
{
- return (m_sm == other.m_sm
- /* We don't compare m_enode. */
- && m_snode == other.m_snode
- && m_stmt == other.m_stmt
- /* We don't compare m_stmt_finder. */
- && m_var == other.m_var
- && m_state == other.m_state
- && m_d->equal_p (*other.m_d)
- && m_trailing_eedge == other.m_trailing_eedge);
+ return m_problem.get ();
}
+ bool calc_best_epath (epath_finder *pf);
+ const exploded_path *get_best_epath () const { return m_best_epath.get (); }
+ unsigned get_epath_length () const;
+
+ void add_duplicate (saved_diagnostic *other);
+ unsigned get_num_dupes () const { return m_duplicates.length (); }
+
+ unsigned get_index () const { return m_idx; }
+
+ bool supercedes_p (const saved_diagnostic &other) const;
+
+ void emit_any_notes () const;
+
//private:
const state_machine *m_sm;
const exploded_node *m_enode;
const supernode *m_snode;
const gimple *m_stmt;
- stmt_finder *m_stmt_finder;
+ std::unique_ptr<stmt_finder> m_stmt_finder;
tree m_var;
+ const svalue *m_sval;
state_machine::state_t m_state;
- pending_diagnostic *m_d;
- exploded_edge *m_trailing_eedge;
+ std::unique_ptr<pending_diagnostic> m_d;
+ const exploded_edge *m_trailing_eedge;
private:
DISABLE_COPY_AND_ASSIGN (saved_diagnostic);
+
+ unsigned m_idx;
+ std::unique_ptr<exploded_path> m_best_epath;
+ std::unique_ptr<feasibility_problem> m_problem;
+
+ auto_vec<const saved_diagnostic *> m_duplicates;
+ auto_delete_vec <pending_note> m_notes;
};
+class path_builder;
+
/* 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
class diagnostic_manager : public log_user
{
public:
- diagnostic_manager (logger *logger, int verbosity);
+ diagnostic_manager (logger *logger, engine *eng, int verbosity);
+
+ engine *get_engine () const { return m_eng; }
- void add_diagnostic (const state_machine *sm,
- const exploded_node *enode,
+ json::object *to_json () const;
+
+ bool add_diagnostic (const state_machine *sm,
+ exploded_node *enode,
const supernode *snode, const gimple *stmt,
- stmt_finder *finder,
- tree var, state_machine::state_t state,
- pending_diagnostic *d);
+ const stmt_finder *finder,
+ tree var,
+ const svalue *sval,
+ state_machine::state_t state,
+ std::unique_ptr<pending_diagnostic> d);
- void add_diagnostic (const exploded_node *enode,
+ bool add_diagnostic (exploded_node *enode,
const supernode *snode, const gimple *stmt,
- stmt_finder *finder,
- pending_diagnostic *d);
+ const stmt_finder *finder,
+ std::unique_ptr<pending_diagnostic> d);
+
+ void add_note (std::unique_ptr<pending_note> pn);
void emit_saved_diagnostics (const exploded_graph &eg);
void emit_saved_diagnostic (const exploded_graph &eg,
- const saved_diagnostic &sd,
- const exploded_path &epath,
- const gimple *stmt,
- int num_dupes);
+ const saved_diagnostic &sd);
unsigned get_num_diagnostics () const
{
{
return m_saved_diagnostics[idx];
}
+ const saved_diagnostic *get_saved_diagnostic (unsigned idx) const
+ {
+ return m_saved_diagnostics[idx];
+ }
private:
- void build_emission_path (const exploded_graph &eg,
+ void build_emission_path (const path_builder &pb,
const exploded_path &epath,
checker_path *emission_path) const;
- void add_events_for_eedge (const exploded_edge &eedge,
- const extrinsic_state &ext_state,
- checker_path *emission_path) const;
+ void add_event_on_final_node (const path_builder &pb,
+ const exploded_node *final_enode,
+ checker_path *emission_path,
+ interesting_t *interest) const;
- void add_events_for_superedge (const exploded_edge &eedge,
+ void add_events_for_eedge (const path_builder &pb,
+ const exploded_edge &eedge,
+ checker_path *emission_path,
+ interesting_t *interest) const;
+
+ bool significant_edge_p (const path_builder &pb,
+ const exploded_edge &eedge) const;
+
+ void add_events_for_superedge (const path_builder &pb,
+ const exploded_edge &eedge,
checker_path *emission_path) const;
void prune_path (checker_path *path,
const state_machine *sm,
- tree var, state_machine::state_t state) const;
+ const svalue *sval,
+ state_machine::state_t state) const;
void prune_for_sm_diagnostic (checker_path *path,
const state_machine *sm,
tree var,
state_machine::state_t state) const;
+ void prune_for_sm_diagnostic (checker_path *path,
+ const state_machine *sm,
+ const svalue *sval,
+ state_machine::state_t state) const;
+ void update_for_unsuitable_sm_exprs (tree *expr) const;
void prune_interproc_events (checker_path *path) const;
+ void consolidate_conditions (checker_path *path) const;
void finish_pruning (checker_path *path) const;
+ engine *m_eng;
auto_delete_vec<saved_diagnostic> m_saved_diagnostics;
const int m_verbosity;
+ int m_num_disabled_diagnostics;
};
+} // namespace ana
+
#endif /* GCC_ANALYZER_DIAGNOSTIC_MANAGER_H */