aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer/program-state.cc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2020-10-28 20:11:41 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2020-10-28 20:11:41 -0400
commitf635f0ce87d687b177b734968f18226d50499e75 (patch)
treee2a8c0ac9ef26b31b88ae552953704a1e66cd3d2 /gcc/analyzer/program-state.cc
parent1a9af271275f4893e28c789c8f1964025694eda1 (diff)
downloadgcc-f635f0ce87d687b177b734968f18226d50499e75.zip
gcc-f635f0ce87d687b177b734968f18226d50499e75.tar.gz
gcc-f635f0ce87d687b177b734968f18226d50499e75.tar.bz2
analyzer: more non-determinism fixes
gcc/analyzer/ChangeLog: * program-state.cc (sm_state_map::on_liveness_change): Sort the leaking svalues before calling on_state_leak. (program_state::detect_leaks): Likewise when calling on_svalue_leak. * region-model-reachability.cc (reachable_regions::mark_escaped_clusters): Likewise when calling on_escaped_function.
Diffstat (limited to 'gcc/analyzer/program-state.cc')
-rw-r--r--gcc/analyzer/program-state.cc26
1 files changed, 23 insertions, 3 deletions
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index 7d719b1..b39e55a 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -517,6 +517,7 @@ sm_state_map::on_liveness_change (const svalue_set &live_svalues,
{
svalue_set svals_to_unset;
+ auto_vec<const svalue *> leaked_svals (m_map.elements ());
for (map_t::iterator iter = m_map.begin ();
iter != m_map.end ();
++iter)
@@ -527,10 +528,20 @@ sm_state_map::on_liveness_change (const svalue_set &live_svalues,
svals_to_unset.add (iter_sval);
entry_t e = (*iter).second;
if (!m_sm.can_purge_p (e.m_state))
- ctxt->on_state_leak (m_sm, iter_sval, e.m_state);
+ leaked_svals.quick_push (iter_sval);
}
}
+ leaked_svals.qsort (svalue::cmp_ptr_ptr);
+
+ unsigned i;
+ const svalue *sval;
+ FOR_EACH_VEC_ELT (leaked_svals, i, sval)
+ {
+ entry_t e = *m_map.get (sval);
+ ctxt->on_state_leak (m_sm, sval, e.m_state);
+ }
+
for (svalue_set::iterator iter = svals_to_unset.begin ();
iter != svals_to_unset.end (); ++iter)
m_map.remove (*iter);
@@ -1181,6 +1192,7 @@ program_state::detect_leaks (const program_state &src_state,
dest_svalues);
}
+ auto_vec <const svalue *> dead_svals (src_svalues.elements ());
for (svalue_set::iterator iter = src_svalues.begin ();
iter != src_svalues.end (); ++iter)
{
@@ -1188,11 +1200,19 @@ program_state::detect_leaks (const program_state &src_state,
/* For each sval reachable from SRC_STATE, determine if it is
live in DEST_STATE: either explicitly reachable, or implicitly
live based on the set of explicitly reachable svalues.
- Call CTXT->on_svalue_leak on those that have ceased to be live. */
+ Record those that have ceased to be live. */
if (!sval->live_p (dest_svalues, dest_state.m_region_model))
- ctxt->on_svalue_leak (sval);
+ dead_svals.quick_push (sval);
}
+ /* Call CTXT->on_svalue_leak on all svals in SRC_STATE that have ceased
+ to be live, sorting them first to ensure deterministic behavior. */
+ dead_svals.qsort (svalue::cmp_ptr_ptr);
+ unsigned i;
+ const svalue *sval;
+ FOR_EACH_VEC_ELT (dead_svals, i, sval)
+ ctxt->on_svalue_leak (sval);
+
/* Purge dead svals from sm-state. */
ctxt->on_liveness_change (dest_svalues, dest_state.m_region_model);