aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2020-01-23 16:33:13 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2020-01-27 10:18:42 -0500
commit6a81cabc14426b642271647b03218a3af19d600f (patch)
tree56549e78861b12a7d50dee21f9c65dfdfffcc69d
parentc15893df6eafc32efd6184379dd7f02c36da7d12 (diff)
downloadgcc-6a81cabc14426b642271647b03218a3af19d600f.zip
gcc-6a81cabc14426b642271647b03218a3af19d600f.tar.gz
gcc-6a81cabc14426b642271647b03218a3af19d600f.tar.bz2
analyzer: fixes to tree_cmp and other comparators
region_model.cc's tree_cmp attempted to verify that the ordering is symmetric by asserting that tree_cmp (x, y) == -tree_cmp (y, x) This condition is too strong: it's only required for a comparator that sign (tree_cmp (x, y)) == -sign (tree_cmp (y, x)) and the incorrect form of the assertion doesn't hold e.g. on s390x where for certain inputs x, y, tree_cmp (x, y) == 1 and tree_cmp (y, x) == -2, breaking the build in "make selftest" in stage1. In any case, these checks are redundant, since qsort_chk performs them. Additionally, there is a potential lack of transitivity in worklist::key_t::cmp where hashval_t values are compared by subtraction, which could fail to be transitive if overflows occur. This patch eliminates the redundant checks and reimplements the hashval_t comparisons in terms of < and >, fixing these issues. gcc/analyzer/ChangeLog: * call-string.cc (call_string::cmp_1): Delete, moving body to... (call_string::cmp): ...here. * call-string.h (call_string::cmp_1): Delete decl. * engine.cc (worklist::key_t::cmp_1): Delete, moving body to... (worklist::key_t::cmp): ...here. Implement hash comparisons via comparison rather than subtraction to avoid overflow issues. * exploded-graph.h (worklist::key_t::cmp_1): Delete decl. * region-model.cc (tree_cmp): Eliminate buggy checking for symmetry.
-rw-r--r--gcc/analyzer/ChangeLog12
-rw-r--r--gcc/analyzer/call-string.cc23
-rw-r--r--gcc/analyzer/call-string.h3
-rw-r--r--gcc/analyzer/engine.cc35
-rw-r--r--gcc/analyzer/exploded-graph.h1
-rw-r--r--gcc/analyzer/region-model.cc16
6 files changed, 21 insertions, 69 deletions
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 345d40f..4a99c3f 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,5 +1,17 @@
2020-01-27 David Malcolm <dmalcolm@redhat.com>
+ * call-string.cc (call_string::cmp_1): Delete, moving body to...
+ (call_string::cmp): ...here.
+ * call-string.h (call_string::cmp_1): Delete decl.
+ * engine.cc (worklist::key_t::cmp_1): Delete, moving body to...
+ (worklist::key_t::cmp): ...here. Implement hash comparisons
+ via comparison rather than subtraction to avoid overflow issues.
+ * exploded-graph.h (worklist::key_t::cmp_1): Delete decl.
+ * region-model.cc (tree_cmp): Eliminate buggy checking for
+ symmetry.
+
+2020-01-27 David Malcolm <dmalcolm@redhat.com>
+
* analyzer.cc (is_named_call_p): Check that fndecl is "extern"
and at file scope. Potentially disregard prefix _ or __ in
fndecl's name. Bail if the identifier is NULL.
diff --git a/gcc/analyzer/call-string.cc b/gcc/analyzer/call-string.cc
index 3d398c3..288953e 100644
--- a/gcc/analyzer/call-string.cc
+++ b/gcc/analyzer/call-string.cc
@@ -149,6 +149,7 @@ call_string::calc_recursion_depth () const
}
/* Comparator for call strings.
+ This implements a version of lexicographical order.
Return negative if A is before B.
Return positive if B is after A.
Return 0 if they are equal. */
@@ -157,28 +158,6 @@ int
call_string::cmp (const call_string &a,
const call_string &b)
{
- int result = cmp_1 (a, b);
-
- /* Check that the ordering is symmetric */
-#if CHECKING_P
- int reversed = cmp_1 (b, a);
- gcc_assert (reversed == -result);
-#endif
-
- /* We should only have 0 for equal pairs. */
- gcc_assert (result != 0
- || a == b);
-
- return result;
-}
-
-/* Implementation of call_string::cmp.
- This implements a version of lexicographical order. */
-
-int
-call_string::cmp_1 (const call_string &a,
- const call_string &b)
-{
unsigned len_a = a.length ();
unsigned len_b = b.length ();
diff --git a/gcc/analyzer/call-string.h b/gcc/analyzer/call-string.h
index 5e362d8..1b5db0a 100644
--- a/gcc/analyzer/call-string.h
+++ b/gcc/analyzer/call-string.h
@@ -69,9 +69,6 @@ public:
void validate () const;
private:
- static int cmp_1 (const call_string &a,
- const call_string &b);
-
auto_vec<const return_superedge *> m_return_edges;
};
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index b39058f..8961c55 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -1634,7 +1634,7 @@ worklist::add_node (exploded_node *enode)
Return 0 if they are equal. */
int
-worklist::key_t::cmp_1 (const worklist::key_t &ka, const worklist::key_t &kb)
+worklist::key_t::cmp (const worklist::key_t &ka, const worklist::key_t &kb)
{
const program_point &point_a = ka.m_enode->get_point ();
const program_point &point_b = kb.m_enode->get_point ();
@@ -1710,9 +1710,12 @@ worklist::key_t::cmp_1 (const worklist::key_t &ka, const worklist::key_t &kb)
sm_state_map *smap_a = state_a.m_checker_states[sm_idx];
sm_state_map *smap_b = state_b.m_checker_states[sm_idx];
- int sm_cmp = smap_a->hash () - smap_b->hash ();
- if (sm_cmp)
- return sm_cmp;
+ hashval_t hash_a = smap_a->hash ();
+ hashval_t hash_b = smap_b->hash ();
+ if (hash_a < hash_b)
+ return -1;
+ else if (hash_a > hash_b)
+ return 1;
}
/* Otherwise, we have two enodes at the same program point but with
@@ -1722,30 +1725,6 @@ worklist::key_t::cmp_1 (const worklist::key_t &ka, const worklist::key_t &kb)
return ka.m_enode->m_index - kb.m_enode->m_index;
}
-/* Comparator for implementing worklist::key_t comparison operators.
- Return negative if KA is before KB
- Return positive if KA is after KB
- Return 0 if they are equal. */
-
-int
-worklist::key_t::cmp (const worklist::key_t &ka, const worklist::key_t &kb)
-{
- int result = cmp_1 (ka, kb);
-
- /* Check that the ordering is symmetric */
-#if CHECKING_P
- int reversed = cmp_1 (kb, ka);
- gcc_assert (reversed == -result);
-#endif
-
- /* We should only have 0 for equal (point, state) pairs. */
- gcc_assert (result != 0
- || (*ka.m_enode->get_ps_key ()
- == *kb.m_enode->get_ps_key ()));
-
- return result;
-}
-
/* exploded_graph's ctor. */
exploded_graph::exploded_graph (const supergraph &sg, logger *logger,
diff --git a/gcc/analyzer/exploded-graph.h b/gcc/analyzer/exploded-graph.h
index a3e758e..c72319c 100644
--- a/gcc/analyzer/exploded-graph.h
+++ b/gcc/analyzer/exploded-graph.h
@@ -652,7 +652,6 @@ private:
}
private:
- static int cmp_1 (const key_t &ka, const key_t &kb);
static int cmp (const key_t &ka, const key_t &kb);
int get_scc_id (const exploded_node *enode) const
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 985f1bd..a986549 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -1843,21 +1843,7 @@ tree_cmp (const void *p1, const void *p2)
const_tree t1 = *(const_tree const *)p1;
const_tree t2 = *(const_tree const *)p2;
- int result = tree_cmp (t1, t2);
-
- /* Check that the ordering is symmetric */
-#if CHECKING_P
- int reversed = tree_cmp (t2, t1);
- gcc_assert (reversed == -result);
-#endif
-
- /* We should only have 0 for equal pairs. */
-#if 0
- gcc_assert (result != 0
- || t1 == t2);
-#endif
-
- return result;
+ return tree_cmp (t1, t2);
}
/* Attempt to merge MAP_REGION_A and MAP_REGION_B into MERGED_MAP_REGION,