aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2000-12-22 09:47:23 -0500
committerJason Merrill <jason@gcc.gnu.org>2000-12-22 09:47:23 -0500
commite5214479a779ad44390aec0694c11c5493aaad83 (patch)
tree03872ce18ff4048a6f1f283f2b1c17a057af6e7a /gcc
parent83ab39071b94a60a1b8fb8e791b8b651b93282fa (diff)
downloadgcc-e5214479a779ad44390aec0694c11c5493aaad83.zip
gcc-e5214479a779ad44390aec0694c11c5493aaad83.tar.gz
gcc-e5214479a779ad44390aec0694c11c5493aaad83.tar.bz2
In partial ordering for a call, ignore parms for which we don't have a real argument.
In partial ordering for a call, ignore parms for which we don't have a real argument. * call.c (joust): Pass len to more_specialized. (add_template_candidate_real): Strip 'this', pass len. * pt.c (more_specialized): Pass len down. Lose explicit_args parm. (get_bindings_order): New fn. Pass len down. (get_bindings_real): Strip 'this', pass len. (fn_type_unification): Likewise. (type_unification_real): Succeed after checking 'len' args. (most_specialized_instantiation): Lose explicit_args parm. * class.c (resolve_address_of_overloaded_function): Strip 'this', pass len. From-SVN: r38460
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog17
-rw-r--r--gcc/cp/call.c21
-rw-r--r--gcc/cp/class.c9
-rw-r--r--gcc/cp/pt.c121
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/partial5.C18
5 files changed, 117 insertions, 69 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0dd5b81..8da2de1 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,4 +1,19 @@
-2000-12-20 Jason Merrill <jason@redhat.com>
+2000-12-22 Jason Merrill <jason@redhat.com>
+
+ In partial ordering for a call, ignore parms for which we don't have
+ a real argument.
+ * call.c (joust): Pass len to more_specialized.
+ (add_template_candidate_real): Strip 'this', pass len.
+ * pt.c (more_specialized): Pass len down. Lose explicit_args parm.
+ (get_bindings_order): New fn. Pass len down.
+ (get_bindings_real): Strip 'this', pass len.
+ (fn_type_unification): Likewise.
+ (type_unification_real): Succeed after checking 'len' args.
+ (most_specialized_instantiation): Lose explicit_args parm.
+ * class.c (resolve_address_of_overloaded_function): Strip 'this',
+ pass len.
+
+2000-12-21 Jason Merrill <jason@redhat.com>
* pt.c (tsubst_decl): A FUNCTION_DECL has DECL_RESULT, not
DECL_TEMPLATE_RESULT.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index e7de1ba..07d7268 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -2147,26 +2147,24 @@ add_template_candidate_real (candidates, tmpl, ctype, explicit_targs,
{
int ntparms = DECL_NTPARMS (tmpl);
tree targs = make_tree_vec (ntparms);
- tree args_without_in_chrg;
+ tree args_without_in_chrg = arglist;
struct z_candidate *cand;
int i;
tree fn;
- /* TEMPLATE_DECLs do not have the in-charge parameter, nor the VTT
- parameter. So, skip it here before attempting to perform
- argument deduction. */
+ /* We don't do deduction on the in-charge parameter, the VTT
+ parameter or 'this'. */
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (tmpl))
+ args_without_in_chrg = TREE_CHAIN (args_without_in_chrg);
+
if ((DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (tmpl)
|| DECL_BASE_CONSTRUCTOR_P (tmpl))
&& TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (tmpl)))
- args_without_in_chrg = tree_cons (NULL_TREE,
- TREE_VALUE (arglist),
- TREE_CHAIN (TREE_CHAIN (arglist)));
- else
- args_without_in_chrg = arglist;
+ args_without_in_chrg = TREE_CHAIN (args_without_in_chrg);
i = fn_type_unification (tmpl, explicit_targs, targs,
args_without_in_chrg,
- return_type, strict);
+ return_type, strict, -1);
if (i != 0)
return candidates;
@@ -5156,7 +5154,8 @@ joust (cand1, cand2, warn)
else if (cand1->template && cand2->template)
winner = more_specialized
(TI_TEMPLATE (cand1->template), TI_TEMPLATE (cand2->template),
- NULL_TREE);
+ /* Never do unification on the 'this' parameter. */
+ TREE_VEC_LENGTH (cand1->convs) - !DECL_STATIC_FUNCTION_P (cand1->fn));
/* or, if not that,
the context is an initialization by user-defined conversion (see
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 60041c5..4e6babd 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -5953,6 +5953,10 @@ resolve_address_of_overloaded_function (target_type,
target_fn_type = TREE_TYPE (target_type);
target_arg_types = TYPE_ARG_TYPES (target_fn_type);
target_ret_type = TREE_TYPE (target_fn_type);
+
+ /* Never do unification on the 'this' parameter. */
+ if (TREE_CODE (target_fn_type) == METHOD_TYPE)
+ target_arg_types = TREE_CHAIN (target_arg_types);
for (fns = overload; fns; fns = OVL_CHAIN (fns))
{
@@ -5975,7 +5979,7 @@ resolve_address_of_overloaded_function (target_type,
targs = make_tree_vec (DECL_NTPARMS (fn));
if (fn_type_unification (fn, explicit_targs, targs,
target_arg_types, target_ret_type,
- DEDUCE_EXACT) != 0)
+ DEDUCE_EXACT, -1) != 0)
/* Argument deduction failed. */
continue;
@@ -5999,8 +6003,7 @@ resolve_address_of_overloaded_function (target_type,
/* Now, remove all but the most specialized of the matches. */
if (matches)
{
- tree match = most_specialized_instantiation (matches,
- explicit_targs);
+ tree match = most_specialized_instantiation (matches);
if (match != error_mark_node)
matches = tree_cons (match, NULL_TREE, NULL_TREE);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 50e7ddf..0a260df 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -113,13 +113,14 @@ static tree add_outermost_template_args PARAMS ((tree, tree));
static void maybe_adjust_types_for_deduction PARAMS ((unification_kind_t, tree*,
tree*));
static int type_unification_real PARAMS ((tree, tree, tree, tree,
- int, unification_kind_t, int));
+ int, unification_kind_t, int, int));
static void note_template_header PARAMS ((int));
static tree maybe_fold_nontype_arg PARAMS ((tree));
static tree convert_nontype_argument PARAMS ((tree, tree));
static tree convert_template_argument PARAMS ((tree, tree, tree, int,
int , tree));
static tree get_bindings_overload PARAMS ((tree, tree, tree));
+static tree get_bindings_order PARAMS ((tree, tree, int));
static int for_each_template_parm PARAMS ((tree, tree_fn_t, void*));
static tree build_template_parm_index PARAMS ((int, int, int, tree, tree));
static int inline_needs_template_parms PARAMS ((tree));
@@ -134,7 +135,7 @@ static tree build_template_decl PARAMS ((tree, tree));
static int mark_template_parm PARAMS ((tree, void *));
static tree tsubst_friend_function PARAMS ((tree, tree));
static tree tsubst_friend_class PARAMS ((tree, tree));
-static tree get_bindings_real PARAMS ((tree, tree, tree, int));
+static tree get_bindings_real PARAMS ((tree, tree, tree, int, int));
static int template_decl_level PARAMS ((tree));
static tree maybe_get_template_decl_from_type_decl PARAMS ((tree));
static int check_cv_quals_for_unify PARAMS ((int, tree, tree));
@@ -7572,10 +7573,8 @@ overload_template_name (type)
all the types, and 1 for complete failure. An error message will be
printed only for an incomplete match.
- If FN is a conversion operator, RETURN_TYPE is the type desired as
- the result of the conversion operator.
-
- TPARMS is a vector of template parameters.
+ If FN is a conversion operator, or we are trying to produce a specific
+ specialization, RETURN_TYPE is the return type desired.
The EXPLICIT_TARGS are explicit template arguments provided via a
template-id.
@@ -7599,13 +7598,18 @@ overload_template_name (type)
[temp.expl.spec], or when taking the address of a function
template, as in [temp.deduct.funcaddr].
- The other arguments are as for type_unification. */
+ LEN is the number of parms to consider before returning success, or -1
+ for all. This is used in partial ordering to avoid comparing parms for
+ which no actual argument was passed, since they are not considered in
+ overload resolution (and are explicitly excluded from consideration in
+ partial ordering in [temp.func.order]/6). */
int
fn_type_unification (fn, explicit_targs, targs, args, return_type,
- strict)
+ strict, len)
tree fn, explicit_targs, targs, args, return_type;
unification_kind_t strict;
+ int len;
{
tree parms;
tree fntype;
@@ -7653,15 +7657,9 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
}
parms = TYPE_ARG_TYPES (fntype);
-
- if (DECL_CONV_FN_P (fn))
- {
- /* This is a template conversion operator. Remove `this', since
- we could be comparing conversions from different classes. */
- parms = TREE_CHAIN (parms);
- args = TREE_CHAIN (args);
- my_friendly_assert (return_type != NULL_TREE, 20000227);
- }
+ /* Never do unification on the 'this' parameter. */
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+ parms = TREE_CHAIN (parms);
if (return_type)
{
@@ -7676,7 +7674,7 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
event. */
result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
targs, parms, args, /*subr=*/0,
- strict, /*allow_incomplete*/1);
+ strict, /*allow_incomplete*/1, len);
if (result == 0)
/* All is well so far. Now, check:
@@ -7769,7 +7767,7 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
*parm = TREE_TYPE (*parm);
}
-/* Like type_unification.
+/* Most parms like fn_type_unification.
If SUBR is 1, we're being called recursively (to unify the
arguments of a function or method parameter of a function
@@ -7777,11 +7775,11 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
static int
type_unification_real (tparms, targs, parms, args, subr,
- strict, allow_incomplete)
+ strict, allow_incomplete, len)
tree tparms, targs, parms, args;
int subr;
unification_kind_t strict;
- int allow_incomplete;
+ int allow_incomplete, len;
{
tree parm, arg;
int i;
@@ -7815,6 +7813,9 @@ type_unification_real (tparms, targs, parms, args, subr,
my_friendly_abort (0);
}
+ if (len == 0)
+ return 0;
+
while (parms
&& parms != void_list_node
&& args
@@ -7887,6 +7888,10 @@ type_unification_real (tparms, targs, parms, args, subr,
if (unify (tparms, targs, parm, arg, sub_strict))
return 1;
+
+ /* Are we done with the interesting parms? */
+ if (--len == 0)
+ return 0;
}
/* Fail if we've reached the end of the parm list, and more args
are present, and the parm list isn't variadic. */
@@ -8738,7 +8743,7 @@ unify (tparms, targs, parm, arg, strict)
return 1;
return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
TYPE_ARG_TYPES (arg), 1,
- DEDUCE_EXACT, 0);
+ DEDUCE_EXACT, 0, -1);
case OFFSET_TYPE:
if (TREE_CODE (arg) != OFFSET_TYPE)
@@ -8854,27 +8859,30 @@ mark_decl_instantiated (result, extern_p)
defer_fn (result);
}
-/* Given two function templates PAT1 and PAT2, and explicit template
- arguments EXPLICIT_ARGS return:
+/* Given two function templates PAT1 and PAT2, return:
1 if PAT1 is more specialized than PAT2 as described in [temp.func.order].
-1 if PAT2 is more specialized than PAT1.
- 0 if neither is more specialized. */
+ 0 if neither is more specialized.
+
+ LEN is passed through to fn_type_unification. */
int
-more_specialized (pat1, pat2, explicit_args)
- tree pat1, pat2, explicit_args;
+more_specialized (pat1, pat2, len)
+ tree pat1, pat2;
+ int len;
{
tree targs;
int winner = 0;
- targs
- = get_bindings_overload (pat1, DECL_TEMPLATE_RESULT (pat2), explicit_args);
+ if (len == 0)
+ return 0;
+
+ targs = get_bindings_order (pat1, DECL_TEMPLATE_RESULT (pat2), len);
if (targs)
--winner;
- targs
- = get_bindings_overload (pat2, DECL_TEMPLATE_RESULT (pat1), explicit_args);
+ targs = get_bindings_order (pat2, DECL_TEMPLATE_RESULT (pat1), len);
if (targs)
++winner;
@@ -8911,12 +8919,12 @@ more_specialized_class (pat1, pat2)
DECL from the function template FN, with the explicit template
arguments EXPLICIT_ARGS. If CHECK_RETTYPE is 1, the return type must
also match. Return NULL_TREE if no satisfactory arguments could be
- found. */
-
+ found. LEN is passed through to fn_type_unification. */
+
static tree
-get_bindings_real (fn, decl, explicit_args, check_rettype)
+get_bindings_real (fn, decl, explicit_args, check_rettype, len)
tree fn, decl, explicit_args;
- int check_rettype;
+ int check_rettype, len;
{
int ntparms = DECL_NTPARMS (fn);
tree targs = make_tree_vec (ntparms);
@@ -8953,18 +8961,16 @@ get_bindings_real (fn, decl, explicit_args, check_rettype)
return NULL_TREE;
}
- /* If FN is a static member function, adjust the type of DECL
- appropriately. */
decl_arg_types = TYPE_ARG_TYPES (decl_type);
- if (DECL_STATIC_FUNCTION_P (fn)
- && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+ /* Never do unification on the 'this' parameter. */
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
decl_arg_types = TREE_CHAIN (decl_arg_types);
i = fn_type_unification (fn, explicit_args, targs,
decl_arg_types,
(check_rettype || DECL_CONV_FN_P (fn)
? TREE_TYPE (decl_type) : NULL_TREE),
- DEDUCE_EXACT);
+ DEDUCE_EXACT, len);
if (i != 0)
return NULL_TREE;
@@ -8978,16 +8984,27 @@ tree
get_bindings (fn, decl, explicit_args)
tree fn, decl, explicit_args;
{
- return get_bindings_real (fn, decl, explicit_args, 1);
+ return get_bindings_real (fn, decl, explicit_args, 1, -1);
}
-/* But for more_specialized, we only care about the parameter types. */
+/* But for resolve_overloaded_unification, we only care about the parameter
+ types. */
static tree
get_bindings_overload (fn, decl, explicit_args)
tree fn, decl, explicit_args;
{
- return get_bindings_real (fn, decl, explicit_args, 0);
+ return get_bindings_real (fn, decl, explicit_args, 0, -1);
+}
+
+/* And for more_specialized, we want to be able to stop partway. */
+
+static tree
+get_bindings_order (fn, decl, len)
+ tree fn, decl;
+ int len;
+{
+ return get_bindings_real (fn, decl, NULL_TREE, 0, len);
}
/* Return the innermost template arguments that, when applied to a
@@ -9029,15 +9046,13 @@ get_class_bindings (tparms, parms, args)
/* In INSTANTIATIONS is a list of <INSTANTIATION, TEMPLATE> pairs.
Pick the most specialized template, and return the corresponding
instantiation, or if there is no corresponding instantiation, the
- template itself. EXPLICIT_ARGS is any template arguments explicitly
- mentioned in a template-id. If there is no most specialized
- template, error_mark_node is returned. If there are no templates
- at all, NULL_TREE is returned. */
+ template itself. If there is no most specialized template,
+ error_mark_node is returned. If there are no templates at all,
+ NULL_TREE is returned. */
tree
-most_specialized_instantiation (instantiations, explicit_args)
+most_specialized_instantiation (instantiations)
tree instantiations;
- tree explicit_args;
{
tree fn, champ;
int fate;
@@ -9048,8 +9063,7 @@ most_specialized_instantiation (instantiations, explicit_args)
champ = instantiations;
for (fn = TREE_CHAIN (instantiations); fn; fn = TREE_CHAIN (fn))
{
- fate = more_specialized (TREE_VALUE (champ),
- TREE_VALUE (fn), explicit_args);
+ fate = more_specialized (TREE_VALUE (champ), TREE_VALUE (fn), -1);
if (fate == 1)
;
else
@@ -9066,8 +9080,7 @@ most_specialized_instantiation (instantiations, explicit_args)
for (fn = instantiations; fn && fn != champ; fn = TREE_CHAIN (fn))
{
- fate = more_specialized (TREE_VALUE (champ),
- TREE_VALUE (fn), explicit_args);
+ fate = more_specialized (TREE_VALUE (champ), TREE_VALUE (fn), -1);
if (fate != 1)
return error_mark_node;
}
@@ -9095,7 +9108,7 @@ most_specialized (fns, decl, explicit_args)
candidates = tree_cons (NULL_TREE, candidate, candidates);
}
- return most_specialized_instantiation (candidates, explicit_args);
+ return most_specialized_instantiation (candidates);
}
/* If DECL is a specialization of some template, return the most
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/partial5.C b/gcc/testsuite/g++.old-deja/g++.pt/partial5.C
new file mode 100644
index 0000000..fa5ebda
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/partial5.C
@@ -0,0 +1,18 @@
+// Test that partial ordering ignores defaulted parms and 'this'.
+
+struct A {
+ template<class T> int f(T) { return 1; }
+ template<class T> int f(T*, int=0) { return 0; }
+ template<class T> int g(T*) { return 0; }
+ template<class T> static int g(T, int=0) { return 1; }
+ template<class T> int h(T*) { return 0; }
+ template<class T> static int h(T, int=0) { return 1; }
+ template<class T> static int j(T*, short y=0) { return 0; }
+ template<class T> static int j(T, int=0) { return 1; }
+};
+
+int main(void) {
+ A a;
+ int *p;
+ return (a.f(p) || a.g(p) || a.h(p) || a.j(p));
+}