diff options
author | Ian Lance Taylor <iant@golang.org> | 2021-09-13 10:37:49 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2021-09-13 10:37:49 -0700 |
commit | e252b51ccde010cbd2a146485d8045103cd99533 (patch) | |
tree | e060f101cdc32bf5e520de8e5275db9d4236b74c /gcc/analyzer/exploded-graph.h | |
parent | f10c7c4596dda99d2ee872c995ae4aeda65adbdf (diff) | |
parent | 104c05c5284b7822d770ee51a7d91946c7e56d50 (diff) | |
download | gcc-e252b51ccde010cbd2a146485d8045103cd99533.zip gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.gz gcc-e252b51ccde010cbd2a146485d8045103cd99533.tar.bz2 |
Merge from trunk revision 104c05c5284b7822d770ee51a7d91946c7e56d50.
Diffstat (limited to 'gcc/analyzer/exploded-graph.h')
-rw-r--r-- | gcc/analyzer/exploded-graph.h | 178 |
1 files changed, 121 insertions, 57 deletions
diff --git a/gcc/analyzer/exploded-graph.h b/gcc/analyzer/exploded-graph.h index deb739f..b9c1767 100644 --- a/gcc/analyzer/exploded-graph.h +++ b/gcc/analyzer/exploded-graph.h @@ -30,21 +30,24 @@ class impl_region_model_context : public region_model_context { public: impl_region_model_context (exploded_graph &eg, - const exploded_node *enode_for_diag, + exploded_node *enode_for_diag, /* TODO: should we be getting the ECs from the old state, rather than the new? */ const program_state *old_state, program_state *new_state, + uncertainty_t *uncertainty, + path_context *path_ctxt, const gimple *stmt, stmt_finder *stmt_finder = NULL); impl_region_model_context (program_state *state, const extrinsic_state &ext_state, + uncertainty_t *uncertainty, logger *logger = NULL); - void warn (pending_diagnostic *d) FINAL OVERRIDE; + bool warn (pending_diagnostic *d) FINAL OVERRIDE; void on_svalue_leak (const svalue *) OVERRIDE; void on_liveness_change (const svalue_set &live_svalues, const region_model *model) FINAL OVERRIDE; @@ -57,7 +60,9 @@ class impl_region_model_context : public region_model_context const svalue *sval, state_machine::state_t state); - void on_condition (tree lhs, enum tree_code op, tree rhs) FINAL OVERRIDE; + void on_condition (const svalue *lhs, + enum tree_code op, + const svalue *rhs) FINAL OVERRIDE; void on_unknown_change (const svalue *sval, bool is_mutable) FINAL OVERRIDE; @@ -68,14 +73,30 @@ class impl_region_model_context : public region_model_context void on_escaped_function (tree fndecl) FINAL OVERRIDE; + uncertainty_t *get_uncertainty () FINAL OVERRIDE; + + void purge_state_involving (const svalue *sval) FINAL OVERRIDE; + + void bifurcate (custom_edge_info *info) FINAL OVERRIDE; + void terminate_path () FINAL OVERRIDE; + const extrinsic_state *get_ext_state () const FINAL OVERRIDE + { + return &m_ext_state; + } + bool get_malloc_map (sm_state_map **out_smap, + const state_machine **out_sm, + unsigned *out_sm_idx) FINAL OVERRIDE; + exploded_graph *m_eg; log_user m_logger; - const exploded_node *m_enode_for_diag; + exploded_node *m_enode_for_diag; const program_state *m_old_state; program_state *m_new_state; const gimple *m_stmt; stmt_finder *m_stmt_finder; const extrinsic_state &m_ext_state; + uncertainty_t *m_uncertainty; + path_context *m_path_ctxt; }; /* A <program_point, program_state> pair, used internally by @@ -186,58 +207,59 @@ class exploded_node : public dnode<eg_traits> void dump (const extrinsic_state &ext_state) const; void dump_processed_stmts (pretty_printer *pp) const; - void dump_saved_diagnostics (pretty_printer *pp, - const diagnostic_manager &dm) const; + void dump_saved_diagnostics (pretty_printer *pp) const; json::object *to_json (const extrinsic_state &ext_state) const; /* The result of on_stmt. */ struct on_stmt_flags { - on_stmt_flags (bool sm_changes) - : m_sm_changes (sm_changes), - m_terminate_path (false) + on_stmt_flags () : m_terminate_path (false) {} static on_stmt_flags terminate_path () { - return on_stmt_flags (true, true); + return on_stmt_flags (true); } - static on_stmt_flags state_change (bool any_sm_changes) - { - return on_stmt_flags (any_sm_changes, false); - } - - /* Did any sm-changes occur handling the stmt. */ - bool m_sm_changes : 1; - /* Should we stop analyzing this path (on_stmt may have already added nodes/edges, e.g. when handling longjmp). */ bool m_terminate_path : 1; private: - on_stmt_flags (bool sm_changes, - bool terminate_path) - : m_sm_changes (sm_changes), - m_terminate_path (terminate_path) + on_stmt_flags (bool terminate_path) + : m_terminate_path (terminate_path) {} }; on_stmt_flags on_stmt (exploded_graph &eg, const supernode *snode, const gimple *stmt, - program_state *state) const; + program_state *state, + uncertainty_t *uncertainty, + path_context *path_ctxt); + void on_stmt_pre (exploded_graph &eg, + const gimple *stmt, + program_state *state, + bool *out_terminate_path, + bool *out_unknown_side_effects, + region_model_context *ctxt); + void on_stmt_post (const gimple *stmt, + program_state *state, + bool unknown_side_effects, + region_model_context *ctxt); + bool on_edge (exploded_graph &eg, const superedge *succ, program_point *next_point, - program_state *next_state) const; + program_state *next_state, + uncertainty_t *uncertainty); void on_longjmp (exploded_graph &eg, const gcall *call, program_state *new_state, - region_model_context *ctxt) const; + region_model_context *ctxt); - void detect_leaks (exploded_graph &eg) const; + void detect_leaks (exploded_graph &eg); const program_point &get_point () const { return m_ps.get_point (); } const supernode *get_supernode () const @@ -269,6 +291,19 @@ class exploded_node : public dnode<eg_traits> m_status = status; } + void add_diagnostic (const saved_diagnostic *sd) + { + m_saved_diagnostics.safe_push (sd); + } + unsigned get_num_diagnostics () const + { + return m_saved_diagnostics.length (); + } + const saved_diagnostic *get_saved_diagnostic (unsigned idx) const + { + return m_saved_diagnostics[idx]; + } + private: DISABLE_COPY_AND_ASSIGN (exploded_node); @@ -278,6 +313,10 @@ private: enum status m_status; + /* The saved_diagnostics at this enode, borrowed from the + diagnostic_manager. */ + auto_vec <const saved_diagnostic *> m_saved_diagnostics; + public: /* The index of this exploded_node. */ const int m_index; @@ -293,28 +332,9 @@ public: class exploded_edge : public dedge<eg_traits> { public: - /* Abstract base class for associating custom data with an - exploded_edge, for handling non-standard edges such as - rewinding from a longjmp, signal handlers, etc. */ - class custom_info_t - { - public: - virtual ~custom_info_t () {} - - /* Hook for making .dot label more readable . */ - virtual void print (pretty_printer *pp) = 0; - - /* Hook for updating MODEL within exploded_path::feasible_p. */ - virtual void update_model (region_model *model, - const exploded_edge &eedge) = 0; - - virtual void add_events_to_path (checker_path *emission_path, - const exploded_edge &eedge) = 0; - }; - exploded_edge (exploded_node *src, exploded_node *dest, const superedge *sedge, - custom_info_t *custom_info); + custom_edge_info *custom_info); ~exploded_edge (); void dump_dot (graphviz_out *gv, const dump_args_t &args) const FINAL OVERRIDE; @@ -330,16 +350,48 @@ class exploded_edge : public dedge<eg_traits> a signal is delivered to a signal-handler. Owned by this class. */ - custom_info_t *m_custom_info; + custom_edge_info *m_custom_info; private: DISABLE_COPY_AND_ASSIGN (exploded_edge); }; +/* Extra data for an exploded_edge that represents dynamic call info ( calls + that doesn't have an underlying superedge representing the call ). */ + +class dynamic_call_info_t : public custom_edge_info +{ +public: + dynamic_call_info_t (const gcall *dynamic_call, + const bool is_returning_call = false) + : m_dynamic_call (dynamic_call), + m_is_returning_call (is_returning_call) + {} + + void print (pretty_printer *pp) const FINAL OVERRIDE + { + if (m_is_returning_call) + pp_string (pp, "dynamic_return"); + else + pp_string (pp, "dynamic_call"); + } + + bool update_model (region_model *model, + const exploded_edge *eedge, + region_model_context *ctxt) const FINAL OVERRIDE; + + void add_events_to_path (checker_path *emission_path, + const exploded_edge &eedge) const FINAL OVERRIDE; +private: + const gcall *m_dynamic_call; + const bool m_is_returning_call; +}; + + /* Extra data for an exploded_edge that represents a rewind from a longjmp to a setjmp (or from a siglongjmp to a sigsetjmp). */ -class rewind_info_t : public exploded_edge::custom_info_t +class rewind_info_t : public custom_edge_info { public: rewind_info_t (const setjmp_record &setjmp_record, @@ -348,16 +400,17 @@ public: m_longjmp_call (longjmp_call) {} - void print (pretty_printer *pp) FINAL OVERRIDE + void print (pretty_printer *pp) const FINAL OVERRIDE { pp_string (pp, "rewind"); } - void update_model (region_model *model, - const exploded_edge &eedge) FINAL OVERRIDE; + bool update_model (region_model *model, + const exploded_edge *eedge, + region_model_context *ctxt) const FINAL OVERRIDE; void add_events_to_path (checker_path *emission_path, - const exploded_edge &eedge) FINAL OVERRIDE; + const exploded_edge &eedge) const FINAL OVERRIDE; const program_point &get_setjmp_point () const { @@ -759,12 +812,20 @@ public: bool maybe_process_run_of_before_supernode_enodes (exploded_node *node); void process_node (exploded_node *node); + bool maybe_create_dynamic_call (const gcall *call, + tree fn_decl, + exploded_node *node, + program_state next_state, + program_point &next_point, + uncertainty_t *uncertainty, + logger *logger); + exploded_node *get_or_create_node (const program_point &point, const program_state &state, - const exploded_node *enode_for_diag); + exploded_node *enode_for_diag); exploded_edge *add_edge (exploded_node *src, exploded_node *dest, const superedge *sedge, - exploded_edge::custom_info_t *custom = NULL); + custom_edge_info *custom = NULL); per_program_point_data * get_or_create_per_program_point_data (const program_point &); @@ -882,9 +943,12 @@ public: exploded_node *get_final_enode () const; - void dump_to_pp (pretty_printer *pp) const; - void dump (FILE *fp) const; - void dump () const; + void dump_to_pp (pretty_printer *pp, + const extrinsic_state *ext_state) const; + void dump (FILE *fp, const extrinsic_state *ext_state) const; + void dump (const extrinsic_state *ext_state = NULL) const; + void dump_to_file (const char *filename, + const extrinsic_state &ext_state) const; bool feasible_p (logger *logger, feasibility_problem **out, engine *eng, const exploded_graph *eg) const; |