From bf924dca4ccc3f8640438400e923a4c508e898e0 Mon Sep 17 00:00:00 2001 From: Yury Gribov Date: Sat, 12 Dec 2015 09:51:54 +0300 Subject: [PATCH 1/5] Fix asymmetric comparison functions. Qsort requires user-defined comparison function to be a total order. One of the requirements for this is being symmetric i.e. return inverse results on element swap. This patch fixes comparison functions to satisfy these conditions. 2015-12-17 Yury Gribov * c-family/c-common.c (resort_field_decl_cmp): Make symmteric. * cp/class.c (method_name_cmp): Ditto. (resort_method_name_cmp): Ditto. * fortran/interface.c (pair_cmp): Ditto. * gimple.c (compare_case_labels): Ditto. * tree-into-ssa.c (insert_phi_nodes_compare_var_infos): Ditto. * tree-vrp.c (compare_case_labels): Ditto. * sel-sched-ir.c (cmp_v_in_regset_pool): Ditto. (bb_top_order_comparator): Ditto. --- gcc/c-family/c-common.c | 4 +++- gcc/cp/class.c | 10 ++++++---- gcc/fortran/interface.c | 6 +++++- gcc/gimple.c | 4 +++- gcc/sel-sched-ir.c | 5 +++-- gcc/tree-into-ssa.c | 5 +---- gcc/tree-vrp.c | 4 +++- 7 files changed, 24 insertions(+), 14 deletions(-) diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 9bc02fc..eecdfb5 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -9956,8 +9956,10 @@ resort_field_decl_cmp (const void *x_p, const void *y_p) resort_data.new_value (&d2, resort_data.cookie); if (d1 < d2) return -1; + if (d1 > d2) + return 1; } - return 1; + return 0; } /* Resort DECL_SORTED_FIELDS because pointers have been reordered. */ diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 216a301..3a740d2 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2188,9 +2188,9 @@ method_name_cmp (const void* m1_p, const void* m2_p) return -1; if (*m2 == NULL_TREE) return 1; - if (DECL_NAME (OVL_CURRENT (*m1)) < DECL_NAME (OVL_CURRENT (*m2))) - return -1; - return 1; + tree d1 = DECL_NAME (OVL_CURRENT (*m1)); + tree d2 = DECL_NAME (OVL_CURRENT (*m2)); + return d1 < d2 ? -1 : d1 > d2 ? 1 : 0; } /* This routine compares two fields like method_name_cmp but using the @@ -2214,8 +2214,10 @@ resort_method_name_cmp (const void* m1_p, const void* m2_p) resort_data.new_value (&d2, resort_data.cookie); if (d1 < d2) return -1; + if (d1 > d2) + return 1; } - return 1; + return 0; } /* Resort TYPE_METHOD_VEC because pointers have been reordered. */ diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index bfd5d36..e4b93c8 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -3109,7 +3109,11 @@ pair_cmp (const void *p1, const void *p2) } if (a2->expr->expr_type != EXPR_VARIABLE) return 1; - return a1->expr->symtree->n.sym < a2->expr->symtree->n.sym; + if (a1->expr->symtree->n.sym < a2->expr->symtree->n.sym) + return 1; + if (a1->expr->symtree->n.sym > a2->expr->symtree->n.sym) + return -1; + return 0; } diff --git a/gcc/gimple.c b/gcc/gimple.c index bf552a7..51f515e 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -2774,7 +2774,9 @@ compare_case_labels (const void *p1, const void *p2) const_tree const case2 = *(const_tree const*)p2; /* The 'default' case label always goes first. */ - if (!CASE_LOW (case1)) + if (!CASE_LOW (case1) && !CASE_LOW (case2)) + return 0; + else if (!CASE_LOW (case1)) return -1; else if (!CASE_LOW (case2)) return 1; diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c index 2a9aa10..2f53d22 100644 --- a/gcc/sel-sched-ir.c +++ b/gcc/sel-sched-ir.c @@ -959,7 +959,7 @@ cmp_v_in_regset_pool (const void *x, const void *xx) return 1; else if (r1 < r2) return -1; - gcc_unreachable (); + return 0; } /* Free the regset pool possibly checking for memory leaks. */ @@ -5935,8 +5935,9 @@ bb_top_order_comparator (const void *x, const void *y) bbs with greater number should go earlier. */ if (rev_top_order_index[bb1->index] > rev_top_order_index[bb2->index]) return -1; - else + else if (rev_top_order_index[bb1->index] < rev_top_order_index[bb2->index]) return 1; + return 0; } /* Create a region for LOOP and return its number. If we don't want diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index 5486d5c..f3b8c02 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -1041,10 +1041,7 @@ insert_phi_nodes_compare_var_infos (const void *a, const void *b) { const var_info *defa = *(var_info * const *)a; const var_info *defb = *(var_info * const *)b; - if (DECL_UID (defa->var) < DECL_UID (defb->var)) - return -1; - else - return 1; + return DECL_UID (defa->var) - DECL_UID (defb->var); } /* Insert PHI nodes at the dominance frontier of blocks with variable diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index acbb70b..cd4eec8 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -5882,7 +5882,9 @@ compare_case_labels (const void *p1, const void *p2) else if (idx1 == idx2) { /* Make sure the default label is first in a group. */ - if (!CASE_LOW (ci1->expr)) + if (!CASE_LOW (ci1->expr) && !CASE_LOW (ci2->expr)) + return 0; + else if (!CASE_LOW (ci1->expr)) return -1; else if (!CASE_LOW (ci2->expr)) return 1; -- 1.9.1