From 9e04ff46157c6f0572e6a5a50085bf25e5679bee Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Fri, 22 May 2020 17:05:54 -0400 Subject: [PATCH 179/179] FIXME: WIP on symbolic-5.c (aliasing) --- gcc/analyzer/store2.cc | 86 +++++++++++++++++++++++++++++++++++++++++- gcc/analyzer/store2.h | 7 +++- gcc/tristate.h | 2 + 3 files changed, 92 insertions(+), 3 deletions(-) diff --git a/gcc/analyzer/store2.cc b/gcc/analyzer/store2.cc index af61e45b908..20d014ff916 100644 --- a/gcc/analyzer/store2.cc +++ b/gcc/analyzer/store2.cc @@ -1069,7 +1069,91 @@ store2::set_value (store2_manager *mgr, const region2 *lhs_reg, const region2 *base_reg = lhs_reg->get_base_region (); binding_cluster2 *cluster = get_or_create_cluster (base_reg); cluster->bind (mgr, lhs_reg, rhs_sval, kind); - // TODO: various kinds of invalidation etc + +#if 0 + if (const symbolic_region2 *sym_base_reg + = base_reg->dyn_cast_symbolic_region2 ()) + { + /* If we set the value to a symbolic region, the code might have + written to other regions. Invalidate our knowledge of regions + that might have been affected by the write. */ + /* FIXME: but what about things that don't even have a + binding cluster yet? + Does initial_value mean + - "the state of the region at the first time that we look at it" or + - "the state of the region at the start of any paths"? */ + for (cluster_map_t::iterator iter = m_cluster_map.begin (); + iter != m_cluster_map.end (); ++iter) + { + const region2 *iter_base_reg = (*iter).first; + binding_cluster2 *iter_cluster = (*iter).second; + if (iter_base_reg != base_reg) + { + tristate t_alias = eval_alias (sym_base_reg, iter_base_reg); + switch (t_alias.get_value ()) + { + default: + gcc_unreachable (); + + case tristate::TS_UNKNOWN: + { + iter_cluster->mark_region_as_unknown (mgr, iter_base_reg); + //iter_cluster->m_touched = true; + } + break; + + case tristate::TS_TRUE: + { + gcc_unreachable (); + // TODO: apply the same change to iter_cluster + /* TODO: guard against infinite recursion + maybe with a hash_set of processed regions? */ + } + break; + + case tristate::TS_FALSE: + /* If they can't be aliases, then don't invalidate this + cluster. */ + break; + } + } + } + } +#endif +} + +/* Determine if SYM_BASE_REG could be an alias of OTHER_BASE_REG. */ + +tristate +store2::eval_alias (const symbolic_region2 *sym_base_reg, + const region2 *other_base_reg) +{ + const svalue2 *sval = sym_base_reg->get_pointer (); + + if (const decl_region2 *decl_reg = other_base_reg->dyn_cast_decl_region2 ()) + { + tree decl = decl_reg->get_decl (); + if (TREE_CODE (decl) == SSA_NAME) + { + /* Can't have pointers to SSA names. */ + return tristate::TS_FALSE; + } + + if (sval->get_kind () == svalue2::SK_INITIAL) + if (!is_global_var (decl) && !escaped_p (decl_reg)) + { + /* The initial value of a pointer can't point to an + unescaped local. */ + return tristate::TS_FALSE; + } + } + + // TODO: any other logic? + /* TODO: perhaps convert this to an alias_oracle * ABC that you ask + questions of, and have a concrete implementation in terms of + region model, so that we can use constraint_manager knowledge? + (and also maybe frontend knowledge?) */ + return tristate::TS_UNKNOWN; } /* FIXME. */ diff --git a/gcc/analyzer/store2.h b/gcc/analyzer/store2.h index 54c33dddc68..7aa3d464966 100644 --- a/gcc/analyzer/store2.h +++ b/gcc/analyzer/store2.h @@ -95,8 +95,8 @@ along with GCC; see the file COPYING3. If not see accesses to other elements are "UNKNOWN" rather than "UNINITIALIZED". - TODO: turn this into symbolic-1.c - TODO: example of memset to zero. */ + TODO: example of memset to zero. + TODO: example of pointer aliasing. */ namespace ana { @@ -394,6 +394,9 @@ public: cluster_map_t::iterator begin () const { return m_cluster_map.begin (); } cluster_map_t::iterator end () const { return m_cluster_map.end (); } + tristate eval_alias (const symbolic_region2 *sym_base_reg, + const region2 *other_base_reg); + private: void remove_overlapping_bindings (store2_manager *mgr, const region2 *reg); diff --git a/gcc/tristate.h b/gcc/tristate.h index e65cb6a09ac..dcd096bf77b 100644 --- a/gcc/tristate.h +++ b/gcc/tristate.h @@ -55,6 +55,8 @@ class tristate { return m_value != other.m_value; } + enum value get_value () const { return m_value; } + private: enum value m_value; }; -- 2.21.0