From eb839598f923c78191f97cc92da2991f7ee42b23 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 16 Apr 2020 13:36:17 -0400 Subject: [PATCH 048/315] FIXME: implement symbolic_region2 --- gcc/analyzer/region-model2.cc | 109 ++++++++++++++++++++++------------ gcc/analyzer/region-model2.h | 37 ++++++------ 2 files changed, 90 insertions(+), 56 deletions(-) diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc index d128cf4b460..0e3aa2f7c63 100644 --- a/gcc/analyzer/region-model2.cc +++ b/gcc/analyzer/region-model2.cc @@ -2654,15 +2654,6 @@ root_region2::get_value_by_name (tree identifier, /* class symbolic_region2 : public map_region2. */ -#if 0 -/* symbolic_region2's copy ctor. */ - -symbolic_region2::symbolic_region2 (const symbolic_region2 &other) -: region2 (other), - m_possibly_null (other.m_possibly_null) -{ -} - /* Compare the fields of this symbolic_region2 with OTHER, returning true if they are equal. For use by region2::operator==. */ @@ -2670,11 +2661,34 @@ symbolic_region2::symbolic_region2 (const symbolic_region2 &other) bool symbolic_region2::compare_fields (const symbolic_region2 &other) const { - return m_possibly_null == other.m_possibly_null; + return m_sval_ptr == other.m_sval_ptr; +} + +/* FIXME. */ + +void +symbolic_region2::dump_to_pp (pretty_printer *pp, bool simple) const +{ + if (simple) + { + pp_string (pp, "*"); + m_sval_ptr->dump_to_pp (pp, simple); + } + else + { + pp_string (pp, "symbolic_region2("); + get_parent_region ()->dump_to_pp (pp, simple); + pp_string (pp, ", "); + print_quoted_type (pp, get_type ()); + pp_string (pp, ", "); + m_sval_ptr->dump_to_pp (pp, simple); + pp_string (pp, ")"); + } } /* Implementation of region2::print_fields vfunc for symbolic_region2. */ +#if 0 void symbolic_region2::print_fields (const region_model2 &model, region2_id this_reg, @@ -2928,6 +2942,8 @@ region_model2_manager::region_model2_manager () // TODO } +/* svalue2 consolidation. */ + /* Return an svalue2 *for a constant_svalue2 for CST_EXPR, creating the constant_svalue2 if necessary. The constant_svalue2 instances are reused, based on pointer equality @@ -2946,6 +2962,35 @@ region_model2_manager::get_or_create_constant_svalue2 (tree cst_expr) // TODO: cst equality vs tree pointer equality? } +svalue2 * +region_model2_manager::get_or_create_initial_value (const region2 *reg) +{ + if (initial_svalue2 **slot = m_initial_values_map.get (reg)) + return *slot; + initial_svalue2 *initial_sval = new initial_svalue2 (reg->get_type (), reg); + m_initial_values_map.put (reg, initial_sval); + return initial_sval; +} + +svalue2 * +region_model2_manager::get_ptr_svalue2 (tree ptr_type, region2 *pointee) +{ + /* If this is a symbolic region from dereferencing a pointer, and the types + match, then return the original pointer. */ + if (symbolic_region2 *sym_reg = pointee->dyn_cast_symbolic_region2 ()) + if (ptr_type == sym_reg->get_pointer ()->get_type ()) + return sym_reg->get_pointer (); + + // FIXME: use ptr_type here: + if (region_svalue2 **slot = m_pointer_values_map.get (pointee)) + return *slot; + region_svalue2 *sval = new region_svalue2 (ptr_type, pointee); + m_pointer_values_map.put (pointee, sval); + return sval; +} + +/* region2 consolidation. */ + /* FIXME. */ decl_region2 * @@ -2996,6 +3041,17 @@ region_model2_manager::get_frame_region (frame_region2 *calling_frame, return const_cast (m_frames.consolidate (frame_reg)); } +region2 * +region_model2_manager::get_symbolic_region (svalue2 *sval) +{ + // FIXME: should only alloc_region_id if consolidation fails + region2 *reg + = new symbolic_region2 (alloc_region_id (), &m_root_region, sval); + return const_cast (m_symbolic_regions.consolidate (reg)); +} + +/* binding consolidation. */ + const concrete_binding2 * region_model2_manager::get_concrete_binding (const region2 *reg, enum binding_key2::kind kind, @@ -3015,27 +3071,6 @@ region_model2_manager::get_symbolic_binding (const region2 *reg, return m_symbolic_binding_key_mgr.consolidate (b); } -svalue2 * -region_model2_manager::get_or_create_initial_value (const region2 *reg) -{ - if (initial_svalue2 **slot = m_initial_values_map.get (reg)) - return *slot; - initial_svalue2 *initial_sval = new initial_svalue2 (reg->get_type (), reg); - m_initial_values_map.put (reg, initial_sval); - return initial_sval; -} - -svalue2 * -region_model2_manager::get_ptr_svalue2 (tree ptr_type, region2 *pointee) -{ - // FIXME: use ptr_type here: - if (region_svalue2 **slot = m_pointer_values_map.get (pointee)) - return *slot; - region_svalue2 *sval = new region_svalue2 (ptr_type, pointee); - m_pointer_values_map.put (pointee, sval); - return sval; -} - /* class region_model2. */ /* FIXME: region_model2's default ctor. */ @@ -4922,10 +4957,10 @@ region_model2::deref_rvalue (svalue2 *ptr_sval, region_model2_context *ctxt) return region2_sval->get_pointee (); } -#if 0 case svalue2::SK_CONSTANT: goto create_symbolic_region2; +#if 0 case svalue2::SK_POISONED: { if (ctxt) @@ -4938,16 +4973,17 @@ region_model2::deref_rvalue (svalue2 *ptr_sval, region_model2_context *ctxt) } goto create_symbolic_region2; } +#endif case svalue2::SK_UNKNOWN: { create_symbolic_region2: /* We need a symbolic_region2 to represent this unknown region2. + FIXME: We don't know if it on the heap, stack, or a global, so use the root region2 as parent. */ - region2 *new_reg - = add_region2 (new symbolic_region2 (m_root_reg, NULL_TREE, false)); - + region2 *new_reg = m_mgr->get_symbolic_region (ptr_sval); +#if 0 /* We need to write the region2 back into the pointer, or we'll get a new, different region2 each time. We do this by changing the meaning of ptr_sval, replacing @@ -4958,13 +4994,12 @@ region_model2::deref_rvalue (svalue2 *ptr_sval, region_model2_context *ctxt) svalue2 *ptr_val = new region_svalue2 (ptr_sval->get_type (), new_reg); replace_svalue2 (ptr_sval, ptr_val); - +#endif return new_reg; } case svalue2::SK_SETJMP: goto create_symbolic_region2; -#endif } gcc_unreachable (); diff --git a/gcc/analyzer/region-model2.h b/gcc/analyzer/region-model2.h index 15ee9ef6bc4..49d168f7f37 100644 --- a/gcc/analyzer/region-model2.h +++ b/gcc/analyzer/region-model2.h @@ -601,7 +601,7 @@ public: RK_STACK, RK_HEAP, RK_ROOT, - //RK_SYMBOLIC, + RK_SYMBOLIC, RK_DECL, RK_FIELD, RK_ELEMENT @@ -1180,18 +1180,15 @@ is_a_helper ::test (region2 *reg) namespace ana { -#if 0 /* Concrete region2 subclass: a region2 to use when dereferencing an unknown pointer. */ class symbolic_region2 : public region2 { public: - symbolic_region2 (unsigned id, region2 *parent, tree type, bool possibly_null) - : region2 (parent, type), - m_possibly_null (possibly_null) + symbolic_region2 (unsigned id, region2 *parent, svalue2 *sval_ptr) + : region2 (id, parent, TREE_TYPE (sval_ptr->get_type ())) {} - symbolic_region2 (const symbolic_region2 &other); const symbolic_region2 *dyn_cast_symbolic_region2 () const FINAL OVERRIDE { return this; } @@ -1200,22 +1197,21 @@ public: bool compare_fields (const symbolic_region2 &other) const; -#if 0 - region2 *clone () const FINAL OVERRIDE; -#endif + enum kind get_kind () const FINAL OVERRIDE { return region2::RK_SYMBOLIC; } + + void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE; - enum kind get_kind () const FINAL OVERRIDE { return RK_SYMBOLIC; } + svalue2 *get_pointer () const { return m_sval_ptr; } #if 0 void print_fields (const region_model2 &model, pretty_printer *pp) const FINAL OVERRIDE; #endif - bool m_possibly_null; +private: + svalue2 *m_sval_ptr; }; -#endif - /* FIXME. */ class decl_region2 : public region2 @@ -1454,8 +1450,12 @@ class region_model2_manager public: region_model2_manager (); + /* svalue2 consolidation. */ svalue2 *get_or_create_constant_svalue2 (tree cst_expr); + svalue2 *get_or_create_initial_value (const region2 *reg); + svalue2 *get_ptr_svalue2 (tree ptr_type, region2 *pointee); + /* region2 consolidation. */ function_region2 *get_region_for_fndecl (tree fndecl, region_model2_context *ctxt); region2 *get_region_for_label (tree label, @@ -1468,10 +1468,13 @@ public: tree element_type, svalue2 *index, region_model2_context *ctxt); - frame_region2 *get_frame_region (frame_region2 *calling_frame, function *fun); + region2 *get_symbolic_region (svalue2 *sval); + + unsigned alloc_region_id () { return m_next_region_id++; } + /* binding consolidation. */ const concrete_binding2 * get_concrete_binding (const region2 *region, enum binding_key2::kind kind, @@ -1482,11 +1485,6 @@ public: enum binding_key2::kind kind, region2 *concrete_offset_region); - svalue2 *get_or_create_initial_value (const region2 *reg); - svalue2 *get_ptr_svalue2 (tree ptr_type, region2 *pointee); - - unsigned alloc_region_id () { return m_next_region_id++; } - private: unsigned m_next_region_id; root_region2 m_root_region; @@ -1519,6 +1517,7 @@ private: #endif uniq_manager m_elements; uniq_manager m_frames; + uniq_manager m_symbolic_regions; uniq_manager m_concrete_binding_key_mgr; uniq_manager m_symbolic_binding_key_mgr; -- 2.26.2