aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-04-07 23:44:48 -0400
committerJason Merrill <jason@gcc.gnu.org>2009-04-07 23:44:48 -0400
commite04c614e09867345ee8ac03390cc75c5f2f1de1e (patch)
tree4b4b914d985e7a40bf89923f3bc3cb2b64094be0 /gcc/cp
parentee618c17faa664adb1b84395199cd62de3b91185 (diff)
downloadgcc-e04c614e09867345ee8ac03390cc75c5f2f1de1e.zip
gcc-e04c614e09867345ee8ac03390cc75c5f2f1de1e.tar.gz
gcc-e04c614e09867345ee8ac03390cc75c5f2f1de1e.tar.bz2
re PR c++/34691 (Default argument checking not performed after overload resolution with C linkage)
PR c++/34691 * name-lookup.c (merge_functions): Keep multiple extern "C" functions. * call.c (joust): Complain about mismatched default arguments in extern "C" functions. * class.c (resolve_address_of_overloaded_function): Handle multiple extern "C" functions. * pt.c (resolve_overloaded_unification): Likewise. From-SVN: r145709
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/call.c48
-rw-r--r--gcc/cp/class.c34
-rw-r--r--gcc/cp/name-lookup.c7
-rw-r--r--gcc/cp/pt.c21
5 files changed, 95 insertions, 25 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 08daf46..264fea4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,15 @@
2009-04-07 Jason Merrill <jason@redhat.com>
+ PR c++/34691
+ * name-lookup.c (merge_functions): Keep multiple extern "C" functions.
+ * call.c (joust): Complain about mismatched default arguments
+ in extern "C" functions.
+ * class.c (resolve_address_of_overloaded_function): Handle multiple
+ extern "C" functions.
+ * pt.c (resolve_overloaded_unification): Likewise.
+
+2009-04-07 Jason Merrill <jason@redhat.com>
+
PR c++/25185
* error.c (dump_function_decl): Don't pretty-print templates
if -fno-pretty-templates.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 745c31f..c942712 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6787,11 +6787,53 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
}
}
- /* If the two functions are the same (this can happen with declarations
- in multiple scopes and arg-dependent lookup), arbitrarily choose one. */
+ /* If the two function declarations represent the same function (this can
+ happen with declarations in multiple scopes and arg-dependent lookup),
+ arbitrarily choose one. But first make sure the default args we're
+ using match. */
if (DECL_P (cand1->fn) && DECL_P (cand2->fn)
&& equal_functions (cand1->fn, cand2->fn))
- return 1;
+ {
+ tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (cand1->fn));
+ tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (cand2->fn));
+
+ gcc_assert (!DECL_CONSTRUCTOR_P (cand1->fn));
+
+ for (i = 0; i < len; ++i)
+ {
+ parms1 = TREE_CHAIN (parms1);
+ parms2 = TREE_CHAIN (parms2);
+ }
+
+ if (off1)
+ parms1 = TREE_CHAIN (parms1);
+ else if (off2)
+ parms2 = TREE_CHAIN (parms2);
+
+ for (; parms1; ++i)
+ {
+ if (!cp_tree_equal (TREE_PURPOSE (parms1),
+ TREE_PURPOSE (parms2)))
+ {
+ if (warn)
+ {
+ permerror (input_location, "default argument mismatch in "
+ "overload resolution");
+ inform (input_location,
+ " candidate 1: %q+#F", cand1->fn);
+ inform (input_location,
+ " candidate 2: %q+#F", cand2->fn);
+ }
+ else
+ add_warning (cand1, cand2);
+ break;
+ }
+ parms1 = TREE_CHAIN (parms1);
+ parms2 = TREE_CHAIN (parms2);
+ }
+
+ return 1;
+ }
tweak:
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index c1885be..1a96384 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -6164,25 +6164,33 @@ resolve_address_of_overloaded_function (tree target_type,
}
else if (TREE_CHAIN (matches))
{
- /* There were too many matches. */
+ /* There were too many matches. First check if they're all
+ the same function. */
+ tree match;
- if (flags & tf_error)
+ fn = TREE_PURPOSE (matches);
+ for (match = TREE_CHAIN (matches); match; match = TREE_CHAIN (match))
+ if (!decls_match (fn, TREE_PURPOSE (matches)))
+ break;
+
+ if (match)
{
- tree match;
+ if (flags & tf_error)
+ {
+ error ("converting overloaded function %qD to type %q#T is ambiguous",
+ DECL_NAME (OVL_FUNCTION (overload)),
+ target_type);
- error ("converting overloaded function %qD to type %q#T is ambiguous",
- DECL_NAME (OVL_FUNCTION (overload)),
- target_type);
+ /* Since print_candidates expects the functions in the
+ TREE_VALUE slot, we flip them here. */
+ for (match = matches; match; match = TREE_CHAIN (match))
+ TREE_VALUE (match) = TREE_PURPOSE (match);
- /* Since print_candidates expects the functions in the
- TREE_VALUE slot, we flip them here. */
- for (match = matches; match; match = TREE_CHAIN (match))
- TREE_VALUE (match) = TREE_PURPOSE (match);
+ print_candidates (matches);
+ }
- print_candidates (matches);
+ return error_mark_node;
}
-
- return error_mark_node;
}
/* Good, exactly one match. Now, convert it to the correct type. */
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index f02605f..2eebb79 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3607,10 +3607,9 @@ merge_functions (tree s1, tree s2)
/* If the function from S2 is already in S1, there is no
need to add it again. For `extern "C"' functions, we
might have two FUNCTION_DECLs for the same function, in
- different namespaces; again, we only need one of them. */
- if (fn1 == fn2
- || (DECL_EXTERN_C_P (fn1) && DECL_EXTERN_C_P (fn2)
- && DECL_NAME (fn1) == DECL_NAME (fn2)))
+ different namespaces, but let's leave them in in case
+ they have different default arguments. */
+ if (fn1 == fn2)
break;
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 92815c0..8dd3579 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -12679,6 +12679,7 @@ resolve_overloaded_unification (tree tparms,
{
tree tempargs = copy_node (targs);
int good = 0;
+ tree goodfn = NULL_TREE;
bool addr_p;
if (TREE_CODE (arg) == ADDR_EXPR)
@@ -12724,8 +12725,13 @@ resolve_overloaded_unification (tree tparms,
if (subargs)
{
elem = tsubst (TREE_TYPE (fn), subargs, tf_none, NULL_TREE);
- good += try_one_overload (tparms, targs, tempargs, parm,
- elem, strict, sub_strict, addr_p);
+ if (try_one_overload (tparms, targs, tempargs, parm,
+ elem, strict, sub_strict, addr_p)
+ && (!goodfn || !decls_match (goodfn, elem)))
+ {
+ goodfn = elem;
+ ++good;
+ }
}
--processing_template_decl;
}
@@ -12738,9 +12744,14 @@ resolve_overloaded_unification (tree tparms,
return false;
else
for (; arg; arg = OVL_NEXT (arg))
- good += try_one_overload (tparms, targs, tempargs, parm,
- TREE_TYPE (OVL_CURRENT (arg)),
- strict, sub_strict, addr_p);
+ if (try_one_overload (tparms, targs, tempargs, parm,
+ TREE_TYPE (OVL_CURRENT (arg)),
+ strict, sub_strict, addr_p)
+ && (!goodfn || !decls_match (goodfn, OVL_CURRENT (arg))))
+ {
+ goodfn = OVL_CURRENT (arg);
+ ++good;
+ }
/* [temp.deduct.type] A template-argument can be deduced from a pointer
to function or pointer to member function argument if the set of