From dcfe240970dcf0c2b0c988241ebe1f00f13341fe Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 13 Apr 2020 11:11:55 -0400 Subject: [PATCH 024/179] FIXME: enough to get it to link --- gcc/analyzer/region-model2.cc | 371 ++++++++++++++++------------------ gcc/analyzer/region-model2.h | 119 ++++++++--- 2 files changed, 270 insertions(+), 220 deletions(-) diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc index ad0bacee148..8911a42cc7a 100644 --- a/gcc/analyzer/region-model2.cc +++ b/gcc/analyzer/region-model2.cc @@ -74,17 +74,6 @@ dump_tree (pretty_printer *pp, tree t) dump_generic_node (pp, t, 0, TDF_SLIM, 0); } -/* Dump T to PP in language-independent form in quotes, for - debugging/logging/dumping purposes. */ - -void -dump_quoted_tree (pretty_printer *pp, tree t) -{ - pp_begin_quote (pp, pp_show_color (pp)); - dump_tree (pp, t); - pp_end_quote (pp, pp_show_color (pp)); -} - /* Equivalent to pp_printf (pp, "%qT", t), to avoid nesting pp_printf calls within other pp_printf calls. @@ -104,29 +93,6 @@ print_quoted_type (pretty_printer *pp, tree t) pp_end_quote (pp, pp_show_color (pp)); } -/* Dump this path_var to PP (which must support %E for trees). - - Express the stack depth using an "@DEPTH" suffix, so e.g. given - void foo (int j); - void bar (int i) - { - foo (i); - } - then: - - the "i" in "bar" would be "(i @ 0)" - - the "j" in "foo" would be "(j @ 1)". */ - -void -path_var::dump (pretty_printer *pp) const -{ - if (m_tree == NULL_TREE) - pp_string (pp, "NULL"); - if (CONSTANT_CLASS_P (m_tree)) - pp_printf (pp, "%qE", m_tree); - else - pp_printf (pp, "(%qE @ %i)", m_tree, m_stack_depth); -} - /* For use in printing a comma-separated list. */ static void @@ -192,6 +158,7 @@ class impl_constraint_manager : public constraint_manager /* Generate a hash value for this svalue2. Most of the work is done by the add_to_hash vfunc. */ +#if 0 hashval_t svalue2::hash () const { @@ -201,6 +168,7 @@ svalue2::hash () const add_to_hash (hstate); return hstate.end (); } +#endif /* Print this svalue2 to PP. */ #if 0 @@ -477,12 +445,13 @@ constant_svalue2::compare_fields (const constant_svalue2 &other) const #endif /* Implementation of svalue2::add_to_hash vfunc for constant_svalue2. */ - +#if 0 void constant_svalue2::add_to_hash (inchash::hash &hstate) const { inchash::add_expr (m_cst_expr, hstate); } +#endif /* Merge the CST_SVAL_A and CST_SVAL_B using MERGER, writing the id of the resulting svalue2 into *MERGED_SVAL. */ @@ -589,12 +558,13 @@ unknown_svalue2::compare_fields (const unknown_svalue2 &) const #endif /* Implementation of svalue2::add_to_hash vfunc for unknown_svalue2. */ - +#if 0 void unknown_svalue2::add_to_hash (inchash::hash &) const { /* Empty. */ } +#endif /* Implementation of svalue2::print_details vfunc for unknown_svalue2. */ #if 0 @@ -606,24 +576,6 @@ unknown_svalue2::print_details (const region_model2 &model ATTRIBUTE_UNUSED, } #endif -/* Get a string for KIND for use in debug dumps. */ - -const char * -poison_kind_to_str (enum poison_kind kind) -{ - switch (kind) - { - default: - gcc_unreachable (); - case POISON_KIND_UNINIT: - return "uninit"; - case POISON_KIND_FREED: - return "freed"; - case POISON_KIND_POPPED_STACK: - return "popped stack"; - } -} - /* class poisoned_svalue2 : public svalue2. */ /* Compare the fields of this poisoned_svalue2 with OTHER, returning true @@ -638,12 +590,13 @@ poisoned_svalue2::compare_fields (const poisoned_svalue2 &other) const #endif /* Implementation of svalue2::add_to_hash vfunc for poisoned_svalue2. */ - +#if 0 void poisoned_svalue2::add_to_hash (inchash::hash &hstate) const { hstate.add_int (m_kind); } +#endif /* Implementation of svalue2::print_details vfunc for poisoned_svalue2. */ #if 0 @@ -839,9 +792,10 @@ region2::operator== (const region2 &other) const for some kinds of casts). */ #if 0 void -region2::set_value (region_model2 &model, region2_id this_reg, svalue2_id rhs_sval, - region_model2_context *ctxt) +region2::set_value (region_model2 &model, region2 *lhs_reg, svalue2 *rhs_sval, + region_model2_context *ctxt) { + gcc_unreachable (); /* Handle some kinds of casting. */ if (m_type) { @@ -874,6 +828,7 @@ region2::set_value (region_model2 &model, region2_id this_reg, svalue2_id rhs_sv } #endif + #if 0 /* Make this region2 (with id THIS_REG) the "active" view of its parent. Any other active view has its value set to "unknown" and descendent values @@ -1172,7 +1127,7 @@ region_model2::copy_array_region2 (region2_id dst_reg, /* Generate a hash value for this region2. The work is done by the add_to_hash vfunc. */ - +#if 0 hashval_t region2::hash () const { @@ -1180,6 +1135,7 @@ region2::hash () const add_to_hash (hstate); return hstate.end (); } +#endif /* Print a one-liner representation of this region2 to PP, assuming that this region2 is within MODEL and its id is THIS_REG. */ @@ -1410,13 +1366,14 @@ region2::region2 (const region2 &other) /* Base implementation of region2::add_to_hash vfunc; subclasses should chain up to this. */ - +#if 0 void region2::add_to_hash (inchash::hash &hstate) const { hstate.add_ptr (m_parent); hstate.add_ptr (m_type); } +#endif /* Base implementation of region2::print_fields vfunc. */ #if 0 @@ -1655,13 +1612,14 @@ map_region2::get (tree key) #endif /* Implementation of region2::add_to_hash vfunc for map_region2. */ - +#if 0 void map_region2::add_to_hash (inchash::hash &hstate) const { region2::add_to_hash (hstate); // TODO } +#endif /* Remove the binding of KEY to its child region2 (but not the child region2 itself). @@ -2023,7 +1981,7 @@ frame_region2::print_fields (const region_model2 &model, #endif /* Implementation of region2::add_to_hash vfunc for frame_region2. */ - +#if 0 void frame_region2::add_to_hash (inchash::hash &hstate) const { @@ -2031,6 +1989,7 @@ frame_region2::add_to_hash (inchash::hash &hstate) const hstate.add_ptr (m_fun); hstate.add_int (m_depth); } +#endif /* class globals_region2 : public scope_region2. */ @@ -2259,13 +2218,14 @@ array_region2::get (key_t key) #endif /* Implementation of region2::add_to_hash vfunc for array_region2. */ - +#if 0 void array_region2::add_to_hash (inchash::hash &hstate) const { region2::add_to_hash (hstate); // TODO } +#endif /* Look for a child region2 with id CHILD_REG within this array_region2. If one is found, write its key to *OUT and return true, @@ -3058,44 +3018,28 @@ symbolic_region2::print_fields (const region_model2 &model, /* region_model2's default ctor. */ -#if 0 region_model2::region_model2 () +: m_current_frame (NULL) { - m_root_reg = add_region2 (new root_region2 ()); - m_constraints = new impl_constraint_manager (this); + //m_root_reg = add_region2 (new root_region2 ()); + //m_constraints = new impl_constraint_manager (this); // TODO } /* region_model2's copy ctor. */ region_model2::region_model2 (const region_model2 &other) -: m_svalue2s (other.m_svalue2s.length ()), - m_region2s (other.m_region2s.length ()), - m_root_reg (other.m_root_reg) +: m_current_frame (NULL) { - /* Clone the svalue2s and region2s. */ - int i; - - svalue2 *svalue2; - FOR_EACH_VEC_ELT (other.m_svalue2s, i, svalue2) - m_svalue2s.quick_push (svalue2->clone ()); - - region2 *region2; - FOR_EACH_VEC_ELT (other.m_region2s, i, region2) - m_region2s.quick_push (region2->clone ()); - - m_constraints = other.m_constraints->clone (this); + // TODO } -#endif /* region_model2's dtor. */ -#if 0 region_model2::~region_model2 () { - delete m_constraints; + // empty? } -#endif /* region_model2's assignment operator. */ #if 0 @@ -3293,7 +3237,9 @@ region_model2::dump_dot (const char *path) const dump_dot_to_file (fp); fclose (fp); } +#endif +// FIXME: /* Dump a multiline representation of this model to PP, showing the region2 hierarchy, the svalue2s, and any constraints. @@ -3304,6 +3250,8 @@ region_model2::dump_dot (const char *path) const void region_model2::dump_to_pp (pretty_printer *pp, bool summarize) const { + gcc_unreachable (); +#if 0 if (summarize) { auto_vec rep_path_vars; @@ -3389,6 +3337,7 @@ region_model2::dump_to_pp (pretty_printer *pp, bool summarize) const pp_string (pp, "constraint manager:"); pp_newline (pp); m_constraints->dump_to_pp (pp); +#endif } /* Dump a multiline representation of this model to FILE. */ @@ -3420,6 +3369,7 @@ region_model2::debug () const dump (false); } +#if 0 /* Dump VEC to PP, in the form "{VEC elements}: LABEL". */ static void @@ -4254,7 +4204,7 @@ region_model2::handle_unrecognized_call (const gcall *call, /* Update this model for the RETURN_STMT, using CTXT to report any diagnostics. */ - +#if 0 void region_model2::on_return (const greturn *return_stmt, region_model2_context *ctxt) { @@ -4265,6 +4215,7 @@ region_model2::on_return (const greturn *return_stmt, region_model2_context *ctx if (lhs && rhs) copy_region (get_lvalue (lhs, ctxt), get_lvalue (rhs, ctxt), ctxt); } +#endif /* Update this model for a call and return of setjmp/sigsetjmp at CALL within ENODE, using CTXT to report any diagnostics. @@ -4358,9 +4309,10 @@ region_model2::on_longjmp (const gcall *longjmp_call, const gcall *setjmp_call, where RHS is for the appropriate edge. */ void -region_model2::handle_phi (const gphi *phi, - tree lhs, tree rhs, bool is_back_edge, - region_model2_context *ctxt) +region_model2::handle_phi (region_model2_manager *mgr, + const gphi *phi, + tree lhs, tree rhs, bool is_back_edge, + region_model2_context *ctxt) { /* For now, don't bother tracking the .MEM SSA names. */ if (tree var = SSA_NAME_VAR (lhs)) @@ -4368,7 +4320,7 @@ region_model2::handle_phi (const gphi *phi, if (VAR_DECL_IS_VIRTUAL_OPERAND (var)) return; - svalue2 *rhs_sval = get_rvalue (rhs, ctxt); + svalue2 *rhs_sval = get_rvalue (mgr, rhs, ctxt); if (is_back_edge && rhs_sval->get_kind () != svalue2::SK_UNKNOWN) { @@ -4380,10 +4332,15 @@ region_model2::handle_phi (const gphi *phi, redundant unknown values; hence we need to purge svalue2s before inserting the state into the exploded graph, to collect unused svalue2s. */ - set_to_new_unknown_value (get_lvalue (lhs, ctxt), TREE_TYPE (lhs), ctxt); +#if 1 + gcc_unreachable (); // FIXME +#else + set_to_new_unknown_value (get_lvalue (mgr, lhs, ctxt), + TREE_TYPE (lhs), ctxt); +#endif } else - set_value (get_lvalue (lhs, ctxt), rhs_sval, ctxt); + set_value (get_lvalue (mgr, lhs, ctxt), rhs_sval, ctxt); if (ctxt) ctxt->on_phi (phi, rhs); @@ -4393,14 +4350,17 @@ region_model2::handle_phi (const gphi *phi, Get the id of the region2 for PV within this region_model2, emitting any diagnostics to CTXT. */ -#if 0 -region2_id -region_model2::get_lvalue_1 (path_var pv, region_model2_context *ctxt) +region2 * +region_model2::get_lvalue_1 (region_model2_manager *mgr, path_var pv, + region_model2_context *ctxt) { tree expr = pv.m_tree; gcc_assert (expr); + gcc_unreachable (); + +#if 0 switch (TREE_CODE (expr)) { default: @@ -4539,8 +4499,8 @@ region_model2::get_lvalue_1 (path_var pv, region_model2_context *ctxt) }; break; } -} #endif +} /* If we see a tree code we don't know how to handle, rather than ICE or generate bogus results, create a dummy region2, and notify @@ -4573,39 +4533,43 @@ assert_compat_types (tree src_type, tree dst_type) /* Get the id of the region2 for PV within this region_model2, emitting any diagnostics to CTXT. */ -#if 0 -region2_id -region_model2::get_lvalue (path_var pv, region_model2_context *ctxt) + +region2 * +region_model2::get_lvalue (region_model2_manager *mgr, path_var pv, + region_model2_context *ctxt) { if (pv.m_tree == NULL_TREE) - return region2_id::null (); + return NULL; - region2 *result_reg = get_lvalue_1 (pv, ctxt); - assert_compat_types (get_region2 (result_reg)->get_type (), - TREE_TYPE (pv.m_tree)); + region2 *result_reg = get_lvalue_1 (mgr, pv, ctxt); + assert_compat_types (result_reg->get_type (), TREE_TYPE (pv.m_tree)); return result_reg; } -#endif /* Get the region2 *for EXPR within this region_model2 (assuming the most recent stack frame if it's a local). */ region2 * -region_model2::get_lvalue (tree expr, region_model2_context *ctxt) +region_model2::get_lvalue (region_model2_manager *mgr, tree expr, + region_model2_context *ctxt) { - return get_lvalue (path_var (expr, get_stack_depth () - 1), ctxt); + return get_lvalue (mgr, path_var (expr, get_stack_depth () - 1), ctxt); } /* Implementation of region_model2::get_rvalue; the latter adds type-checking. Get the value of PV within this region_model2, emitting any diagnostics to CTXT. */ -#if 0 -svalue2_id -region_model2::get_rvalue_1 (path_var pv, region_model2_context *ctxt) + +svalue2 * +region_model2::get_rvalue_1 (region_model2_manager *mgr, path_var pv, + region_model2_context *ctxt) { gcc_assert (pv.m_tree); + gcc_unreachable (); + +#if 0 switch (TREE_CODE (pv.m_tree)) { default: @@ -4651,31 +4615,34 @@ region_model2::get_rvalue_1 (path_var pv, region_model2_context *ctxt) return get_region2 (var_reg)->get_value (*this, true, ctxt); } } +#endif } /* Get the value of PV within this region_model2, emitting any diagnostics to CTXT. */ -svalue2_id -region_model2::get_rvalue (path_var pv, region_model2_context *ctxt) +svalue2 * +region_model2::get_rvalue (region_model2_manager *mgr, path_var pv, + region_model2_context *ctxt) { if (pv.m_tree == NULL_TREE) - return svalue2_id::null (); - svalue2 *result_sval = get_rvalue_1 (pv, ctxt); + return NULL; + + svalue2 *result_sval = get_rvalue_1 (mgr, pv, ctxt); - assert_compat_types (get_svalue2 (result_sval)->get_type (), - TREE_TYPE (pv.m_tree)); + assert_compat_types (result_sval->get_type (), TREE_TYPE (pv.m_tree)); return result_sval; } -#endif + /* Get the value of EXPR within this region_model2 (assuming the most recent stack frame if it's a local). */ svalue2 * -region_model2::get_rvalue (tree expr, region_model2_context *ctxt) +region_model2::get_rvalue (region_model2_manager *mgr, tree expr, + region_model2_context *ctxt) { - return get_rvalue (path_var (expr, get_stack_depth () - 1), ctxt); + return get_rvalue (mgr, path_var (expr, get_stack_depth () - 1), ctxt); } /* Return an svalue2 *for a pointer to RID of type PTR_TYPE, reusing @@ -5023,47 +4990,48 @@ region_model2::deref_rvalue (tree ptr, region_model2_context *ctxt) /* Set the value of the region2 given by LHS_REG to the value given by RHS_SVAL. */ -#if 0 + void region_model2::set_value (region2 *lhs_reg, svalue2 *rhs_sval, - region_model2_context *ctxt) + region_model2_context *ctxt) { gcc_assert (lhs_reg); - gcc_assert (!rhs_sval.null_p ()); - get_region2 (lhs_reg)->set_value (*this, lhs_reg, rhs_sval, ctxt); + gcc_assert (rhs_sval); + + // TODO: + gcc_unreachable (); } /* Set the value of the region2 given by LHS to the value given by RHS. */ void -region_model2::set_value (tree lhs, tree rhs, region_model2_context *ctxt) +region_model2::set_value (region_model2_manager *mgr, + tree lhs, tree rhs, region_model2_context *ctxt) { - region2 *lhs_reg = get_lvalue (lhs, ctxt); - svalue2 *rhs_sval = get_rvalue (rhs, ctxt); + region2 *lhs_reg = get_lvalue (mgr, lhs, ctxt); + svalue2 *rhs_sval = get_rvalue (mgr, rhs, ctxt); gcc_assert (lhs_reg); - gcc_assert (!rhs_sval.null_p ()); + gcc_assert (rhs_sval); set_value (lhs_reg, rhs_sval, ctxt); } -#endif /* Determine what is known about the condition "LHS_SVAL OP RHS_SVAL" within this model. */ -#if 0 + tristate -region_model2::eval_condition (svalue2 *lhs_sval, - enum tree_code op, - svalue2 *rhs_sval) const +region_model2::eval_condition (svalue2 *lhs, + enum tree_code op, + svalue2 *rhs) const { - svalue2 *lhs = get_svalue2 (lhs_sval); - svalue2 *rhs = get_svalue2 (rhs_sval); - /* For now, make no attempt to capture constraints on floating-point values. */ if ((lhs->get_type () && FLOAT_TYPE_P (lhs->get_type ())) || (rhs->get_type () && FLOAT_TYPE_P (rhs->get_type ()))) return tristate::unknown (); + gcc_unreachable (); +#if 0 tristate ts = eval_condition_without_cm (lhs_sval, op, rhs_sval); if (ts.is_known ()) @@ -5071,6 +5039,7 @@ region_model2::eval_condition (svalue2 *lhs_sval, /* Otherwise, try constraints. */ return m_constraints->eval_condition (lhs_sval, op, rhs_sval); +#endif } /* Determine what is known about the condition "LHS_SVAL OP RHS_SVAL" within @@ -5079,7 +5048,7 @@ region_model2::eval_condition (svalue2 *lhs_sval, This is exposed so that impl_region_model2_context::on_state_leak can check for equality part-way through region_model2::purge_unused_svalue2s without risking creating new ECs. */ - +#if 0 tristate region_model2::eval_condition_without_cm (svalue2 *lhs_sval, enum tree_code op, @@ -5168,6 +5137,7 @@ region_model2::eval_condition_without_cm (svalue2 *lhs_sval, return tristate::TS_UNKNOWN; } +#endif /* Attempt to add the constraint "LHS OP RHS" to this region_model2. If it is consistent with existing constraints, add it, and return true. @@ -5175,16 +5145,17 @@ region_model2::eval_condition_without_cm (svalue2 *lhs_sval, Use CTXT for reporting any diagnostics associated with the accesses. */ bool -region_model2::add_constraint (tree lhs, enum tree_code op, tree rhs, - region_model2_context *ctxt) +region_model2::add_constraint (region_model2_manager *mgr, + tree lhs, enum tree_code op, tree rhs, + region_model2_context *ctxt) { /* For now, make no attempt to capture constraints on floating-point values. */ if (FLOAT_TYPE_P (TREE_TYPE (lhs)) || FLOAT_TYPE_P (TREE_TYPE (rhs))) return true; - svalue2 *lhs_sval = get_rvalue (lhs, ctxt); - svalue2 *rhs_sval = get_rvalue (rhs, ctxt); + svalue2 *lhs_sval = get_rvalue (mgr, lhs, ctxt); + svalue2 *rhs_sval = get_rvalue (mgr, rhs, ctxt); tristate t_cond = eval_condition (lhs_sval, op, rhs_sval); @@ -5197,6 +5168,8 @@ region_model2::add_constraint (tree lhs, enum tree_code op, tree rhs, if (t_cond.is_false ()) return false; + gcc_unreachable (); +#if 0 /* Store the constraint. */ m_constraints->add_constraint (lhs_sval, op, rhs_sval); @@ -5218,10 +5191,12 @@ region_model2::add_constraint (tree lhs, enum tree_code op, tree rhs, when synthesizing constraints as above. */ if (ctxt) ctxt->on_condition (lhs, op, rhs); +#endif return true; } +#if 0 /* Subroutine of region_model2::add_constraint for handling optimized && and || conditionals. @@ -5358,17 +5333,20 @@ region_model2::add_any_constraints_from_gcall (enum tree_code op, Use CTXT for reporting any diagnostics associated with the accesses. */ tristate -region_model2::eval_condition (tree lhs, - enum tree_code op, - tree rhs, - region_model2_context *ctxt) +region_model2::eval_condition (region_model2_manager *mgr, + tree lhs, + enum tree_code op, + tree rhs, + region_model2_context *ctxt) { /* For now, make no attempt to model constraints on floating-point values. */ if (FLOAT_TYPE_P (TREE_TYPE (lhs)) || FLOAT_TYPE_P (TREE_TYPE (rhs))) return tristate::unknown (); - return eval_condition (get_rvalue (lhs, ctxt), op, get_rvalue (rhs, ctxt)); + return eval_condition (get_rvalue (mgr, lhs, ctxt), + op, + get_rvalue (mgr, rhs, ctxt)); } /* If SID is a constant value, return the underlying tree constant. @@ -5594,7 +5572,8 @@ region_model2::update_for_phis (const supernode *snode, than program state). */ bool -region_model2::maybe_update_for_edge (const superedge &edge, +region_model2::maybe_update_for_edge (region_model2_manager *mgr, + const superedge &edge, const gimple *last_stmt, region_model2_context *ctxt) { @@ -5607,7 +5586,7 @@ region_model2::maybe_update_for_edge (const superedge &edge, case SUPEREDGE_CALL: { const call_superedge *call_edge = as_a (&edge); - update_for_call_superedge (*call_edge, ctxt); + update_for_call_superedge (mgr, *call_edge, ctxt); } break; @@ -5636,14 +5615,15 @@ region_model2::maybe_update_for_edge (const superedge &edge, if (const gcond *cond_stmt = dyn_cast (last_stmt)) { const cfg_superedge *cfg_sedge = as_a (&edge); - return apply_constraints_for_gcond (*cfg_sedge, cond_stmt, ctxt); + return apply_constraints_for_gcond (mgr, *cfg_sedge, cond_stmt, ctxt); } if (const gswitch *switch_stmt = dyn_cast (last_stmt)) { const switch_cfg_superedge *switch_sedge = as_a (&edge); - return apply_constraints_for_gswitch (*switch_sedge, switch_stmt, ctxt); + return apply_constraints_for_gswitch (mgr, *switch_sedge, switch_stmt, + ctxt); } return true; @@ -5655,7 +5635,8 @@ region_model2::maybe_update_for_edge (const superedge &edge, caller's frame. */ #if 1 void -region_model2::update_for_call_superedge (const call_superedge &call_edge, +region_model2::update_for_call_superedge (region_model2_manager *mgr, + const call_superedge &call_edge, region_model2_context *ctxt) { /* Build a vec of argument svalue2_id, using the current top @@ -5666,7 +5647,7 @@ region_model2::update_for_call_superedge (const call_superedge &call_edge, for (unsigned i = 0; i < gimple_call_num_args (call_stmt); i++) { tree arg = gimple_call_arg (call_stmt, i); - arg_svals.quick_push (get_rvalue (arg, ctxt)); + arg_svals.quick_push (get_rvalue (mgr, arg, ctxt)); } push_frame (call_edge.get_callee_function (), &arg_svals, ctxt); @@ -5675,11 +5656,12 @@ region_model2::update_for_call_superedge (const call_superedge &call_edge, /* Pop the top-most frame_region2 from the stack, and copy the return region2's values (if any) into the region2 for the lvalue of the LHS of the call (if any). */ -#if 0 void region_model2::update_for_return_superedge (const return_superedge &return_edge, - region_model2_context *ctxt) + region_model2_context *ctxt) { + gcc_unreachable (); +#if 0 region2 *stack_reg = get_stack_region2 *(); stack_region2 *stack = get_region2 (stack_reg); @@ -5707,19 +5689,20 @@ region_model2::update_for_return_superedge (const return_superedge &return_edge, don't special-case the result sids (as was done in pop_frame). */ purge_unused_svalue2s (&stats, ctxt); } -} #endif +} /* Update this region_model2 with a summary of the effect of calling and returning from CG_SEDGE. TODO: Currently this is extremely simplistic: we merely set the return value to "unknown". A proper implementation would e.g. update sm-state, and presumably be reworked to support multiple outcomes. */ -#if 0 void region_model2::update_for_call_summary (const callgraph_superedge &cg_sedge, - region_model2_context *ctxt) + region_model2_context *ctxt) { + gcc_unreachable (); +#if 0 /* For now, set any return value to "unknown". */ const gcall *call_stmt = cg_sedge.get_call_stmt (); tree lhs = gimple_call_lhs (call_stmt); @@ -5727,8 +5710,9 @@ region_model2::update_for_call_summary (const callgraph_superedge &cg_sedge, set_to_new_unknown_value (get_lvalue (lhs, ctxt), TREE_TYPE (lhs), ctxt); // TODO: actually implement some kind of summary here -} #endif +} + /* Given a true or false edge guarded by conditional statement COND_STMT, determine appropriate constraints for the edge to be taken. @@ -5738,9 +5722,10 @@ region_model2::update_for_call_summary (const callgraph_superedge &cg_sedge, (and so the edge should not be taken). */ bool -region_model2::apply_constraints_for_gcond (const cfg_superedge &sedge, - const gcond *cond_stmt, - region_model2_context *ctxt) +region_model2::apply_constraints_for_gcond (region_model2_manager *mgr, + const cfg_superedge &sedge, + const gcond *cond_stmt, + region_model2_context *ctxt) { ::edge cfg_edge = sedge.get_cfg_edge (); gcc_assert (cfg_edge != NULL); @@ -5751,7 +5736,7 @@ region_model2::apply_constraints_for_gcond (const cfg_superedge &sedge, tree rhs = gimple_cond_rhs (cond_stmt); if (cfg_edge->flags & EDGE_FALSE_VALUE) op = invert_tree_comparison (op, false /* honor_nans */); - return add_constraint (lhs, op, rhs, ctxt); + return add_constraint (mgr, lhs, op, rhs, ctxt); } /* Given an EDGE guarded by SWITCH_STMT, determine appropriate constraints @@ -5763,9 +5748,10 @@ region_model2::apply_constraints_for_gcond (const cfg_superedge &sedge, (and so the edge should not be taken). */ bool -region_model2::apply_constraints_for_gswitch (const switch_cfg_superedge &edge, - const gswitch *switch_stmt, - region_model2_context *ctxt) +region_model2::apply_constraints_for_gswitch (region_model2_manager *mgr, + const switch_cfg_superedge &edge, + const gswitch *switch_stmt, + region_model2_context *ctxt) { tree index = gimple_switch_index (switch_stmt); tree case_label = edge.get_case_label (); @@ -5777,13 +5763,13 @@ region_model2::apply_constraints_for_gswitch (const switch_cfg_superedge &edge, if (upper_bound) { /* Range. */ - if (!add_constraint (index, GE_EXPR, lower_bound, ctxt)) + if (!add_constraint (mgr, index, GE_EXPR, lower_bound, ctxt)) return false; - return add_constraint (index, LE_EXPR, upper_bound, ctxt); + return add_constraint (mgr, index, LE_EXPR, upper_bound, ctxt); } else /* Single-value. */ - return add_constraint (index, EQ_EXPR, lower_bound, ctxt); + return add_constraint (mgr, index, EQ_EXPR, lower_bound, ctxt); } else { @@ -5803,14 +5789,16 @@ region_model2::apply_constraints_for_gswitch (const switch_cfg_superedge &edge, /* Exclude this range-valued case. For now, we just exclude the boundary values. TODO: exclude the values within the region2. */ - if (!add_constraint (index, NE_EXPR, other_lower_bound, ctxt)) + if (!add_constraint (mgr, index, NE_EXPR, other_lower_bound, + ctxt)) return false; - if (!add_constraint (index, NE_EXPR, other_upper_bound, ctxt)) + if (!add_constraint (mgr, index, NE_EXPR, other_upper_bound, + ctxt)) return false; } else /* Exclude this single-valued case. */ - if (!add_constraint (index, NE_EXPR, other_lower_bound, ctxt)) + if (!add_constraint (mgr, index, NE_EXPR, other_lower_bound, ctxt)) return false; } return true; @@ -5834,6 +5822,7 @@ region_model2::get_stack_region2 *() const } #endif +// FIXME: /* Create a new frame_region2 for a call to FUN and push it onto the stack. @@ -5842,23 +5831,15 @@ region_model2::get_stack_region2 *() const Otherwise, populate them with unknown values. Return the region2 *of the new frame_region2. */ -#if 0 + region2 * -region_model2::push_frame (function *fun, vec *arg_svals, - region_model2_context *ctxt) +region_model2::push_frame (function *fun, vec *arg_svals, + region_model2_context *ctxt) { - return get_root_region2 ()->push_frame (this, fun, arg_svals, ctxt); + gcc_unreachable (); + //return get_root_region2 ()->push_frame (this, fun, arg_svals, ctxt); } -/* Get the region2 *of the top-most frame in this region_model2's stack, - if any. */ - -region2_id -region_model2::get_current_frame *() const -{ - return get_root_region2 ()->get_current_frame *(*this); -} -#endif /* Get the function of the top-most frame in this region_model2's stack. There must be such a frame. */ @@ -5882,17 +5863,16 @@ region_model2::pop_frame (region2 *result_dst_reg, #endif /* Get the number of frames in this region_model2's stack. */ -#if 0 + int region_model2::get_stack_depth () const { - stack_region2 *stack = get_root_region2 ()->get_stack_region2 (this); - if (stack) - return stack->get_num_frames (); + frame_region2 *frame = get_current_frame (); + if (frame) + return frame->get_depth (); else return 0; } -#endif /* Get the function * at DEPTH within the call stack. */ #if 0 @@ -6847,11 +6827,12 @@ test_tree_cmp_on_constants () void assert_condition (const location &loc, + region_model2_manager *mgr, region_model2 &model, tree lhs, tree_code op, tree rhs, tristate expected) { - tristate actual = model.eval_condition (lhs, op, rhs, NULL); + tristate actual = model.eval_condition (mgr, lhs, op, rhs, NULL); ASSERT_EQ_AT (loc, actual, expected); } @@ -6897,14 +6878,13 @@ assert_dump_eq (const location &loc, SELFTEST_END_STMT /* Smoketest for region_model2::dump_to_pp. */ -#if 0 + static void test_dump () { + // FIXME: + //region_model2_manager mgr; region_model2 model; - model.get_root_region2 ()->ensure_stack_region2 (&model); - model.get_root_region2 ()->ensure_globals_region2 (&model); - model.get_root_region2 ()->ensure_heap_region2 (&model); ASSERT_DUMP_EQ (model, false, "r0: {kind: `root', parent: null, sval: null}\n" @@ -6988,9 +6968,10 @@ test_dump_2 () tree int_17 = build_int_cst (integer_type_node, 17); tree int_m3 = build_int_cst (integer_type_node, -3); + region_model2_manager mgr; region_model2 model; - model.set_value (c_x, int_17, NULL); - model.set_value (c_y, int_m3, NULL); + model.set_value (&mgr, c_x, int_17, NULL); + model.set_value (&mgr, c_y, int_m3, NULL); /* Simplified dump. */ ASSERT_DUMP_EQ (model, true, "c.x: 17, c.y: -3"); @@ -7016,6 +6997,8 @@ test_dump_2 () " constraints:\n"); } +#if 0 + /* Verify that dumps can show array elements. */ static void @@ -8202,10 +8185,10 @@ test_malloc_constraints () void analyzer_region_model2_cc_tests () { -#if 0 test_tree_cmp_on_constants (); test_dump (); test_dump_2 (); +#if 0 test_dump_3 (); test_get_representative_tree (); test_unique_constants (); diff --git a/gcc/analyzer/region-model2.h b/gcc/analyzer/region-model2.h index f5117e2b207..1849858f95d 100644 --- a/gcc/analyzer/region-model2.h +++ b/gcc/analyzer/region-model2.h @@ -162,8 +162,10 @@ public: void print (const region_model2 &model, pretty_printer *pp) const; +#if 0 virtual void dump_dot_to_pp (const region_model2 &model, pretty_printer *pp) const; +#endif virtual region_svalue2 *dyn_cast_region_svalue2 () { return NULL; } virtual constant_svalue2 *dyn_cast_constant_svalue2 () { return NULL; } @@ -178,11 +180,15 @@ public: protected: svalue2 (tree type) : m_type (type) {} +#if 0 virtual void add_to_hash (inchash::hash &hstate) const = 0; +#endif private: +#if 0 virtual void print_details (const region_model2 &model, pretty_printer *pp) const = 0; +#endif tree m_type; }; @@ -204,9 +210,11 @@ public: enum kind get_kind () const FINAL OVERRIDE { return SK_REGION; } +#if 0 void dump_dot_to_pp (const region_model2 &model, pretty_printer *pp) const FINAL OVERRIDE; +#endif region_svalue2 *dyn_cast_region_svalue2 () FINAL OVERRIDE { return this; } @@ -224,11 +232,15 @@ public: enum tree_code op, region_svalue2 *rhs_ptr); +#if 0 void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE; +#endif private: +#if 0 void print_details (const region_model2 &model, pretty_printer *pp) const FINAL OVERRIDE; +#endif region2 *m_reg; }; @@ -264,7 +276,9 @@ public: enum kind get_kind () const FINAL OVERRIDE { return SK_CONSTANT; } +#if 0 void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE; +#endif constant_svalue2 *dyn_cast_constant_svalue2 () FINAL OVERRIDE { return this; } const constant_svalue2 *dyn_cast_constant_svalue2 () const FINAL OVERRIDE @@ -284,10 +298,12 @@ public: constant_svalue2 *rhs); private: +#if 0 void print_details (const region_model2 &model, pretty_printer *pp) const FINAL OVERRIDE; - +#endif + tree m_cst_expr; }; @@ -321,14 +337,18 @@ public: enum kind get_kind () const FINAL OVERRIDE { return SK_UNKNOWN; } +#if 0 void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE; +#endif unknown_svalue2 *dyn_cast_unknown_svalue2 () FINAL OVERRIDE { return this; } private: +#if 0 void print_details (const region_model2 &model, pretty_printer *pp) const FINAL OVERRIDE; +#endif }; /* An enum describing a particular kind of "poisoned" value. */ @@ -363,16 +383,20 @@ public: enum kind get_kind () const FINAL OVERRIDE { return SK_POISONED; } +#if 0 void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE; +#endif poisoned_svalue2 *dyn_cast_poisoned_svalue2 () FINAL OVERRIDE { return this; } enum poison_kind get_poison_kind () const { return m_kind; } private: +#if 0 void print_details (const region_model2 &model, pretty_printer *pp) const FINAL OVERRIDE; +#endif enum poison_kind m_kind; }; @@ -429,7 +453,9 @@ public: enum kind get_kind () const FINAL OVERRIDE { return SK_SETJMP; } +#if 0 void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE; +#endif setjmp_svalue2 *dyn_cast_setjmp_svalue2 () FINAL OVERRIDE { return this; } @@ -438,9 +464,11 @@ public: const setjmp_record &get_setjmp_record () const { return m_setjmp_record; } private: +#if 0 void print_details (const region_model2 &model, pretty_printer *pp) const FINAL OVERRIDE; +#endif setjmp_record m_setjmp_record; }; @@ -539,24 +567,28 @@ public: void print (const region_model2 &model, pretty_printer *pp) const; +#if 0 virtual void dump_dot_to_pp (const region_model2 &model, pretty_printer *pp) const; - +#endif void dump_to_pp (const region_model2 &model, pretty_printer *pp, const char *prefix, bool is_last_child) const; +#if 0 virtual void dump_child_label (const region_model2 &model, region2 *child, pretty_printer *pp) const; - +#endif #if 0 void add_view (region_id view_rid, region_model2 *model); region_id get_view (tree type, region_model2 *model) const; region_id get_active_view () const { return m_active_view_rid; } bool is_view_p () const { return m_is_view; } #endif +#if 0 virtual void validate (const region_model2 &model) const; +#endif bool non_null_p (const region_model2 &model) const; @@ -566,12 +598,13 @@ public: region2 (const region2 &other); #endif +#if 0 virtual void add_to_hash (inchash::hash &hstate) const; virtual void print_fields (const region_model2 &model, pretty_printer *pp) const; - +#endif private: -#if 0 +#if 0 void become_active_view (region_model2 &model, region_id this_rid); void deactivate_any_active_view (region_model2 &model); void deactivate_view (region_model2 &model, region_id this_view_rid); @@ -627,14 +660,15 @@ public: map_region2 *dyn_cast_map_region2 () FINAL OVERRIDE { return this; } +#if 0 void dump_dot_to_pp (const region_model2 &model, pretty_printer *pp) const FINAL OVERRIDE; - void dump_child_label (const region_model2 &model, region2 *child, pretty_printer *pp) const FINAL OVERRIDE; +#endif #if 0 region2_id get_or_create (region_model2 *model, @@ -668,11 +702,13 @@ public: size_t elements () const { return m_map.elements (); } protected: +#if 0 void add_to_hash (inchash::hash &hstate) const OVERRIDE; void print_fields (const region_model2 &model, pretty_printer *pp) const OVERRIDE; void validate (const region_model2 &model) const FINAL OVERRIDE; +#endif private: /* Mapping from tree to child region2. */ @@ -821,11 +857,12 @@ public: region2 *clone () const FINAL OVERRIDE; #endif enum kind get_kind () const FINAL OVERRIDE { return RK_FRAME; } +#if 0 void print_fields (const region_model2 &model, pretty_printer *pp) const FINAL OVERRIDE; void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE; - +#endif /* map_region2 vfuncs. */ bool valid_key_p (tree key) const FINAL OVERRIDE; @@ -1002,6 +1039,7 @@ public: } array_region2 (const array_region2 &other); +#if 0 void dump_dot_to_pp (const region_model2 &model, pretty_printer *pp) const FINAL OVERRIDE; @@ -1010,6 +1048,7 @@ public: region2 *child, pretty_printer *pp) const FINAL OVERRIDE; +#endif /* region2 vfuncs. */ #if 0 @@ -1050,11 +1089,13 @@ public: key_t *out) const; #endif +#if 0 void add_to_hash (inchash::hash &hstate) const OVERRIDE; void print_fields (const region_model2 &model, pretty_printer *pp) const OVERRIDE; void validate (const region_model2 &model) const FINAL OVERRIDE; +#endif static key_t key_from_constant (tree cst); tree constant_from_key (key_t key); @@ -1099,14 +1140,15 @@ public: enum kind get_kind () const FINAL OVERRIDE { return RK_STACK; } +#if 0 void dump_child_label (const region_model2 &model, region2 *child, pretty_printer *pp) const FINAL OVERRIDE; +#endif #if 0 void push_frame (region2 *frame_rid); - region2 *get_current_frame_id () const; void pop_frame (region_model2 *model, region2_id result_dst_rid, bool purge, purge_stats *stats, region_model2_context *ctxt); @@ -1120,13 +1162,16 @@ public: const region_model2 &model) const; #endif +#if 0 void validate (const region_model2 &model) const FINAL OVERRIDE; - +#endif private: +#if 0 void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE; void print_fields (const region_model2 &model, pretty_printer *pp) const FINAL OVERRIDE; +#endif #if 0 auto_vec m_frame_rids; @@ -1202,16 +1247,17 @@ public: enum kind get_kind () const FINAL OVERRIDE { return RK_ROOT; } +#if 0 void dump_child_label (const region_model2 &model, region2 *child, pretty_printer *pp) const FINAL OVERRIDE; +#endif #if 0 region2_id push_frame (region_model2 *model, function *fun, vec *arg_sids, region_model2_context *ctxt); - region2_id get_current_frame_id (const region_model2 &model) const; void pop_frame (region_model2 *model, region2_id result_dst_rid, bool purge, purge_stats *stats, region_model2_context *ctxt); @@ -1238,13 +1284,17 @@ public: svalue2 *get_value_by_name (tree identifier, const region_model2 &model) const; +#if 0 void validate (const region_model2 &model) const FINAL OVERRIDE; +#endif private: +#if 0 void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE; void print_fields (const region_model2 &model, pretty_printer *pp) const FINAL OVERRIDE; +#endif #if 0 region2_id m_stack_rid; @@ -1291,8 +1341,10 @@ public: enum kind get_kind () const FINAL OVERRIDE { return RK_SYMBOLIC; } +#if 0 void print_fields (const region_model2 &model, pretty_printer *pp) const FINAL OVERRIDE; +#endif bool m_possibly_null; }; @@ -1368,11 +1420,13 @@ class region_model2 const cfg_superedge *last_cfg_superedge, region_model2_context *ctxt); - void handle_phi (const gphi *phi, + void handle_phi (region_model2_manager *mgr, + const gphi *phi, tree lhs, tree rhs, bool is_back_edge, region_model2_context *ctxt); - bool maybe_update_for_edge (const superedge &edge, + bool maybe_update_for_edge (region_model2_manager *mgr, + const superedge &edge, const gimple *last_stmt, region_model2_context *ctxt); @@ -1384,7 +1438,7 @@ class region_model2 #endif region2 *push_frame (function *fun, vec *arg_sids, region_model2_context *ctxt); - frame_region2 *get_current_frame () const; + frame_region2 *get_current_frame () const { return m_current_frame; } function * get_current_function () const; void pop_frame (region2 *result_dst, bool purge, purge_stats *stats, @@ -1397,10 +1451,14 @@ class region_model2 void replace_svalue2 (svalue2_id sid, svalue2 *new_sval); #endif - region2 *get_lvalue (path_var pv, region_model2_context *ctxt); - region2 *get_lvalue (tree expr, region_model2_context *ctxt); - svalue2 *get_rvalue (path_var pv, region_model2_context *ctxt); - svalue2 *get_rvalue (tree expr, region_model2_context *ctxt); + region2 *get_lvalue (region_model2_manager *mgr, + path_var pv, region_model2_context *ctxt); + region2 *get_lvalue (region_model2_manager *mgr, + tree expr, region_model2_context *ctxt); + svalue2 *get_rvalue (region_model2_manager *mgr, + path_var pv, region_model2_context *ctxt); + svalue2 *get_rvalue (region_model2_manager *mgr, + tree expr, region_model2_context *ctxt); #if 0 svalue2_id get_or_create_ptr_svalue2 (tree ptr_type, region2_id id); @@ -1422,7 +1480,8 @@ class region_model2 #endif void set_value (region2 *lhs_reg, svalue2 *rhs_sval, region_model2_context *ctxt); - void set_value (tree lhs, tree rhs, region_model2_context *ctxt); + void set_value (region_model2_manager *mgr, + tree lhs, tree rhs, region_model2_context *ctxt); svalue2 *set_to_new_unknown_value (region2 *dst_reg, tree type, region_model2_context *ctxt); void copy_region (region2 *dst_reg, region2 *src_reg, @@ -1435,11 +1494,13 @@ class region_model2 enum tree_code op, svalue2_id rhs) const; #endif - tristate eval_condition (tree lhs, + tristate eval_condition (region_model2_manager *mgr, + tree lhs, enum tree_code op, tree rhs, region_model2_context *ctxt); - bool add_constraint (tree lhs, enum tree_code op, tree rhs, + bool add_constraint (region_model2_manager *mgr, + tree lhs, enum tree_code op, tree rhs, region_model2_context *ctxt); #if 0 tree maybe_get_constant (svalue2_id sid) const; @@ -1501,10 +1562,12 @@ class region_model2 #endif private: -#if 0 - region2_id get_lvalue_1 (path_var pv, region_model2_context *ctxt); - svalue2_id get_rvalue_1 (path_var pv, region_model2_context *ctxt); + region2 *get_lvalue_1 (region_model2_manager *mgr, path_var pv, + region_model2_context *ctxt); + svalue2 *get_rvalue_1 (region_model2_manager *mgr, path_var pv, + region_model2_context *ctxt); +#if 0 void copy_struct_region2 (region2_id dst_rid, struct_region2 *dst_reg, struct_region2 *src_reg, region_model2_context *ctxt); void copy_union_region2 (region2_id dst_rid, union_region2 *src_reg, @@ -1528,16 +1591,19 @@ class region_model2 const gcall *call, region_model2_context *ctxt); #endif - void update_for_call_superedge (const call_superedge &call_edge, + void update_for_call_superedge (region_model2_manager *mgr, + const call_superedge &call_edge, region_model2_context *ctxt); void update_for_return_superedge (const return_superedge &return_edge, region_model2_context *ctxt); void update_for_call_summary (const callgraph_superedge &cg_sedge, region_model2_context *ctxt); - bool apply_constraints_for_gcond (const cfg_superedge &edge, + bool apply_constraints_for_gcond (region_model2_manager *mgr, + const cfg_superedge &edge, const gcond *cond_stmt, region_model2_context *ctxt); - bool apply_constraints_for_gswitch (const switch_cfg_superedge &edge, + bool apply_constraints_for_gswitch (region_model2_manager *mgr, + const switch_cfg_superedge &edge, const gswitch *switch_stmt, region_model2_context *ctxt); #if 0 @@ -1557,6 +1623,7 @@ class region_model2 region2_id m_root_rid; constraint_manager *m_constraints; // TODO: embed, rather than dynalloc? #endif + frame_region2 *m_current_frame; }; /* Some region_model2 activity could lead to warnings (e.g. attempts to use an -- 2.21.0