aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/exploded-graph.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/analyzer/exploded-graph.h')
-rw-r--r--gcc/analyzer/exploded-graph.h178
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;