summaryrefslogtreecommitdiffstats
path: root/gcc/cp/call.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/call.c')
-rw-r--r--gcc/cp/call.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index fda38de4d9a..f193a4b7b16 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -44,6 +44,7 @@ static tree build_new_method_call PROTO((tree, tree, tree, tree, int));
static tree build_field_call PROTO((tree, tree, tree, tree));
static struct z_candidate * tourney PROTO((struct z_candidate *));
+static int equal_functions PROTO((tree, tree));
static int joust PROTO((struct z_candidate *, struct z_candidate *, int));
static int compare_ics PROTO((tree, tree));
static tree build_over_call PROTO((struct z_candidate *, tree, int));
@@ -4768,6 +4769,20 @@ add_warning (winner, loser)
winner->warnings);
}
+/* Returns true iff functions are equivalent. Equivalent functions are
+ not identical only if one is a function-local extern function.
+ This assumes that function-locals don't have TREE_PERMANENT. */
+
+static inline int
+equal_functions (fn1, fn2)
+ tree fn1;
+ tree fn2;
+{
+ if (!TREE_PERMANENT (fn1) || !TREE_PERMANENT (fn2))
+ return decls_match (fn1, fn2);
+ return fn1 == fn2;
+}
+
/* Compare two candidates for overloading as described in
[over.match.best]. Return values:
@@ -4963,6 +4978,12 @@ joust (cand1, cand2, warn)
}
}
+ /* If the two functions are the same (this can happen with declarations
+ in multiple scopes and arg-dependent lookup), arbitrarily choose one. */
+ if (DECL_P (cand1->fn) && DECL_P (cand2->fn)
+ && equal_functions (cand1->fn, cand2->fn))
+ return 1;
+
tweak:
/* Extension: If the worst conversion for one candidate is worse than the
OpenPOWER on IntegriCloud