From 3f2e35a02a7c2898d6f05dc63eb2c2ec1de28ee3 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Thu, 21 May 2020 12:31:04 -0400 Subject: [PATCH 170/179] FIXME: call simplify_for_binding in binding_cluster2::get_representative_path_vars --- gcc/analyzer/store2.cc | 62 ++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/gcc/analyzer/store2.cc b/gcc/analyzer/store2.cc index 2c910bc0677..51809a6c96e 100644 --- a/gcc/analyzer/store2.cc +++ b/gcc/analyzer/store2.cc @@ -213,6 +213,36 @@ symbolic_binding2::dump_to_pp (pretty_printer *pp, bool simple) const #endif +/* The store is oblivious to the types of the svalues bound within + it: any type can get bound at any location. + Simplify any casts before binding. + + For example, if we have: + struct big { int ia[1024]; }; + struct big src, dst; + memcpy (&dst, &src, sizeof (struct big)); + this reaches us in gimple form as: + MEM [(char * {ref-all})&dst] + = MEM [(char * {ref-all})&src]; + Using cast_region when handling the MEM_REF would give us: + INIT_VAL(CAST_REG(unsigned char[4096], src)) + as rhs_sval, but we can fold that into a cast svalue2: + CAST(unsigned char[4096], INIT_VAL(src)) + We can discard that cast from the svalue when binding it in + the store for "dst", and simply store: + cluster for: dst + key: {kind: direct, start: 0, size: 32768, next: 32768} + value: ‘struct big’ {INIT_VAL(src)} + FIXME: should we only do this if the sizes are the same? */ + +static const svalue2 * +simplify_for_binding (const svalue2 *sval) +{ + if (const svalue2 *cast_sval = sval->maybe_undo_cast ()) + sval = cast_sval; + return sval; +} + /* class binding_cluster2. */ /* FIXME. */ @@ -633,6 +663,8 @@ binding_cluster2::get_representative_path_vars (const region2 *base_reg, auto_vec *out_pvs) const { + sval = simplify_for_binding (sval); + for (map_t::iterator iter = m_map.begin (); iter != m_map.end (); ++iter) { const binding_key2 *key = (*iter).first; @@ -1006,36 +1038,6 @@ store2::get_any_binding (store2_manager *mgr, const region2 *reg) return (*cluster_slot)->get_any_binding (mgr, reg); } -/* The store is oblivious to the types of the svalues bound within - it: any type can get bound at any location. - Simplify any casts before binding. - - For example, if we have: - struct big { int ia[1024]; }; - struct big src, dst; - memcpy (&dst, &src, sizeof (struct big)); - this reaches us in gimple form as: - MEM [(char * {ref-all})&dst] - = MEM [(char * {ref-all})&src]; - Using cast_region when handling the MEM_REF would give us: - INIT_VAL(CAST_REG(unsigned char[4096], src)) - as rhs_sval, but we can fold that into a cast svalue2: - CAST(unsigned char[4096], INIT_VAL(src)) - We can discard that cast from the svalue when binding it in - the store for "dst", and simply store: - cluster for: dst - key: {kind: direct, start: 0, size: 32768, next: 32768} - value: ‘struct big’ {INIT_VAL(src)} - FIXME: should we only do this if the sizes are the same? */ - -static const svalue2 * -simplify_for_binding (const svalue2 *sval) -{ - if (const svalue2 *cast_sval = sval->maybe_undo_cast ()) - sval = cast_sval; - return sval; -} - void store2::set_value (store2_manager *mgr, const region2 *lhs_reg, const svalue2 *rhs_sval, enum binding_kind kind) -- 2.21.0