Commit 62e4a758 by Nathan Sidwell Committed by Nathan Sidwell

cp-tree.h (unification_kind_t): Add DEDUCE_ORDER.

cp:
	* cp-tree.h (unification_kind_t): Add DEDUCE_ORDER.
	(more_specialized): Add deduction parameter.
	* call.c (joust): Adjust more_specialized call.
	* pt.c (UNIFY_ALLOW_OUTER_MORE_CV_QUAL,
	UNIFY_ALLOW_OUTER_LESS_CV_QUAL): New unify flags.
	(get_bindings_order): Remove.
	(get_bindings_real): Add DEDUCE parameter.
	(maybe_adjust_types_for_deduction): Return extra unify flags. Do
	REFERENCE_TYPE jig for DEDUCE_ORDER.
	(type_unification_real): Deal with DEDUCE_ORDER. Use result of
	maybe_adjust_types_for_deduction.
	(more_specialized): Add DEDUCE parameter. Call get_bindings_real
	directly.
	(try_one_overload): Use result of maybe_adjust_types_for_deduction.
	(check_cv_quals_for_unify): Use new unify qualifier flags.
	(unify): Clear new unify qualifier flags.
	(get_bindings_real): Add DEDUCE parameter.
	(get_bindings): Adjust call to get_bindings_real.
	(get_bindings_overload): Likewise.
	(most_specialized_instantiation): Adjust call to
	more_specialized.
testsuite:
	* g++.old-deja/g++.martin/sts_partial.C: Remove XFAIL.
	* g++.old-deja/g++.pt/spec35.C: New test.
	* g++.old-deja/g++.pt/spec36.C: New test.

From-SVN: r39182
parent 0bbcfbaf
2001-01-22 Nathan Sidwell <nathan@codesourcery.com>
* cp-tree.h (unification_kind_t): Add DEDUCE_ORDER.
(more_specialized): Add deduction parameter.
* call.c (joust): Adjust more_specialized call.
* pt.c (UNIFY_ALLOW_OUTER_MORE_CV_QUAL,
UNIFY_ALLOW_OUTER_LESS_CV_QUAL): New unify flags.
(get_bindings_order): Remove.
(get_bindings_real): Add DEDUCE parameter.
(maybe_adjust_types_for_deduction): Return extra unify flags. Do
REFERENCE_TYPE jig for DEDUCE_ORDER.
(type_unification_real): Deal with DEDUCE_ORDER. Use result of
maybe_adjust_types_for_deduction.
(more_specialized): Add DEDUCE parameter. Call get_bindings_real
directly.
(try_one_overload): Use result of maybe_adjust_types_for_deduction.
(check_cv_quals_for_unify): Use new unify qualifier flags.
(unify): Clear new unify qualifier flags.
(get_bindings_real): Add DEDUCE parameter.
(get_bindings): Adjust call to get_bindings_real.
(get_bindings_overload): Likewise.
(most_specialized_instantiation): Adjust call to
more_specialized.
2001-01-19 Jason Merrill <jason@redhat.com> 2001-01-19 Jason Merrill <jason@redhat.com>
* decl2.c (flag_vtable_thunks): Also depend on ENABLE_NEW_GXX_ABI. * decl2.c (flag_vtable_thunks): Also depend on ENABLE_NEW_GXX_ABI.
......
...@@ -5196,6 +5196,7 @@ joust (cand1, cand2, warn) ...@@ -5196,6 +5196,7 @@ joust (cand1, cand2, warn)
else if (cand1->template && cand2->template) else if (cand1->template && cand2->template)
winner = more_specialized winner = more_specialized
(TI_TEMPLATE (cand1->template), TI_TEMPLATE (cand2->template), (TI_TEMPLATE (cand1->template), TI_TEMPLATE (cand2->template),
DEDUCE_ORDER,
/* Never do unification on the 'this' parameter. */ /* Never do unification on the 'this' parameter. */
TREE_VEC_LENGTH (cand1->convs) TREE_VEC_LENGTH (cand1->convs)
- DECL_NONSTATIC_MEMBER_FUNCTION_P (cand1->fn)); - DECL_NONSTATIC_MEMBER_FUNCTION_P (cand1->fn));
......
...@@ -3209,14 +3209,15 @@ extern int function_depth; ...@@ -3209,14 +3209,15 @@ extern int function_depth;
/* in pt.c */ /* in pt.c */
/* These values are used for the `STRICT' parameter to type_unfication and /* These values are used for the `STRICT' parameter to type_unification and
fn_type_unification. Their meanings are described with the fn_type_unification. Their meanings are described with the
documentation for fn_type_unification. */ documentation for fn_type_unification. */
typedef enum unification_kind_t { typedef enum unification_kind_t {
DEDUCE_CALL, DEDUCE_CALL,
DEDUCE_CONV, DEDUCE_CONV,
DEDUCE_EXACT DEDUCE_EXACT,
DEDUCE_ORDER
} unification_kind_t; } unification_kind_t;
/* Macros for operating on a template instantation level node, represented /* Macros for operating on a template instantation level node, represented
...@@ -4143,7 +4144,7 @@ extern tree instantiate_template PARAMS ((tree, tree)); ...@@ -4143,7 +4144,7 @@ extern tree instantiate_template PARAMS ((tree, tree));
extern int fn_type_unification PARAMS ((tree, tree, tree, tree, tree, unification_kind_t, int)); extern int fn_type_unification PARAMS ((tree, tree, tree, tree, tree, unification_kind_t, int));
extern tree tinst_for_decl PARAMS ((void)); extern tree tinst_for_decl PARAMS ((void));
extern void mark_decl_instantiated PARAMS ((tree, int)); extern void mark_decl_instantiated PARAMS ((tree, int));
extern int more_specialized PARAMS ((tree, tree, int)); extern int more_specialized PARAMS ((tree, tree, int, int));
extern void mark_class_instantiated PARAMS ((tree, int)); extern void mark_class_instantiated PARAMS ((tree, int));
extern void do_decl_instantiation PARAMS ((tree, tree, tree)); extern void do_decl_instantiation PARAMS ((tree, tree, tree));
extern void do_type_instantiation PARAMS ((tree, tree, int)); extern void do_type_instantiation PARAMS ((tree, tree, int));
......
...@@ -87,6 +87,8 @@ static htab_t local_specializations; ...@@ -87,6 +87,8 @@ static htab_t local_specializations;
#define UNIFY_ALLOW_DERIVED 4 #define UNIFY_ALLOW_DERIVED 4
#define UNIFY_ALLOW_INTEGER 8 #define UNIFY_ALLOW_INTEGER 8
#define UNIFY_ALLOW_OUTER_LEVEL 16 #define UNIFY_ALLOW_OUTER_LEVEL 16
#define UNIFY_ALLOW_OUTER_MORE_CV_QUAL 32
#define UNIFY_ALLOW_OUTER_LESS_CV_QUAL 64
#define GTB_VIA_VIRTUAL 1 /* The base class we are examining is #define GTB_VIA_VIRTUAL 1 /* The base class we are examining is
virtual, or a base class of a virtual virtual, or a base class of a virtual
...@@ -111,7 +113,7 @@ static tree coerce_template_parms PARAMS ((tree, tree, tree, int, int)); ...@@ -111,7 +113,7 @@ static tree coerce_template_parms PARAMS ((tree, tree, tree, int, int));
static void tsubst_enum PARAMS ((tree, tree, tree)); static void tsubst_enum PARAMS ((tree, tree, tree));
static tree add_to_template_args PARAMS ((tree, tree)); static tree add_to_template_args PARAMS ((tree, tree));
static tree add_outermost_template_args PARAMS ((tree, tree)); static tree add_outermost_template_args PARAMS ((tree, tree));
static void maybe_adjust_types_for_deduction PARAMS ((unification_kind_t, tree*, static int maybe_adjust_types_for_deduction PARAMS ((unification_kind_t, tree*,
tree*)); tree*));
static int type_unification_real PARAMS ((tree, tree, tree, tree, static int type_unification_real PARAMS ((tree, tree, tree, tree,
int, unification_kind_t, int, int)); int, unification_kind_t, int, int));
...@@ -121,7 +123,6 @@ static tree convert_nontype_argument PARAMS ((tree, tree)); ...@@ -121,7 +123,6 @@ static tree convert_nontype_argument PARAMS ((tree, tree));
static tree convert_template_argument PARAMS ((tree, tree, tree, int, static tree convert_template_argument PARAMS ((tree, tree, tree, int,
int , tree)); int , tree));
static tree get_bindings_overload PARAMS ((tree, tree, 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 int for_each_template_parm PARAMS ((tree, tree_fn_t, void*));
static tree build_template_parm_index PARAMS ((int, int, int, tree, tree)); static tree build_template_parm_index PARAMS ((int, int, int, tree, tree));
static int inline_needs_template_parms PARAMS ((tree)); static int inline_needs_template_parms PARAMS ((tree));
...@@ -136,7 +137,7 @@ static tree build_template_decl PARAMS ((tree, tree)); ...@@ -136,7 +137,7 @@ static tree build_template_decl PARAMS ((tree, tree));
static int mark_template_parm PARAMS ((tree, void *)); static int mark_template_parm PARAMS ((tree, void *));
static tree tsubst_friend_function PARAMS ((tree, tree)); static tree tsubst_friend_function PARAMS ((tree, tree));
static tree tsubst_friend_class PARAMS ((tree, tree)); static tree tsubst_friend_class PARAMS ((tree, tree));
static tree get_bindings_real PARAMS ((tree, tree, tree, int, int)); static tree get_bindings_real PARAMS ((tree, tree, tree, int, int, int));
static int template_decl_level PARAMS ((tree)); static int template_decl_level PARAMS ((tree));
static tree maybe_get_template_decl_from_type_decl PARAMS ((tree)); static tree maybe_get_template_decl_from_type_decl PARAMS ((tree));
static int check_cv_quals_for_unify PARAMS ((int, tree, tree)); static int check_cv_quals_for_unify PARAMS ((int, tree, tree));
...@@ -7681,13 +7682,15 @@ instantiate_template (tmpl, targ_ptr) ...@@ -7681,13 +7682,15 @@ instantiate_template (tmpl, targ_ptr)
[temp.deduct.conv]. [temp.deduct.conv].
DEDUCE_EXACT: DEDUCE_EXACT:
We are deducing arguments when doing an explicit instantiation
as in [temp.explicit], when determining an explicit specialization
as in [temp.expl.spec], or when taking the address of a function
template, as in [temp.deduct.funcaddr].
DEDUCE_ORDER:
We are deducing arguments when calculating the partial We are deducing arguments when calculating the partial
ordering between specializations of function or class ordering between specializations of function or class
templates, as in [temp.func.order] and [temp.class.order], templates, as in [temp.func.order] and [temp.class.order].
when doing an explicit instantiation as in [temp.explicit],
when determining an explicit specialization as in
[temp.expl.spec], or when taking the address of a function
template, as in [temp.deduct.funcaddr].
LEN is the number of parms to consider before returning success, or -1 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 for all. This is used in partial ordering to avoid comparing parms for
...@@ -7793,12 +7796,14 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type, ...@@ -7793,12 +7796,14 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
the argument passed to the call, or the type of the value the argument passed to the call, or the type of the value
initialized with the result of the conversion function. */ initialized with the result of the conversion function. */
static void static int
maybe_adjust_types_for_deduction (strict, parm, arg) maybe_adjust_types_for_deduction (strict, parm, arg)
unification_kind_t strict; unification_kind_t strict;
tree* parm; tree* parm;
tree* arg; tree* arg;
{ {
int result = 0;
switch (strict) switch (strict)
{ {
case DEDUCE_CALL: case DEDUCE_CALL:
...@@ -7817,8 +7822,43 @@ maybe_adjust_types_for_deduction (strict, parm, arg) ...@@ -7817,8 +7822,43 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
case DEDUCE_EXACT: case DEDUCE_EXACT:
/* There is nothing to do in this case. */ /* There is nothing to do in this case. */
return; return 0;
case DEDUCE_ORDER:
/* DR 214. [temp.func.order] is underspecified, and leads to no
ordering between things like `T *' and `T const &' for `U *'.
The former has T=U and the latter T=U*. The former looks more
specialized and John Spicer considers it well-formed (the EDG
compiler accepts it).
John also confirms that deduction should proceed as in a function
call. Which implies the usual ARG and PARM bashing as DEDUCE_CALL.
However, in ordering, ARG can have REFERENCE_TYPE, but no argument
to an actual call can have such a type.
When deducing against a REFERENCE_TYPE, we can either not change
PARM's type, or we can change ARG's type too. The latter, though
seemingly more safe, turns out to give the following quirk. Consider
deducing a call to a `const int *' with the following template
function parameters
#1; T const *const & ; T = int
#2; T *const & ; T = const int
#3; T * ; T = const int
It looks like #1 is the more specialized. Taken pairwise, #1 is
more specialized than #2 and #2 is more specialized than #3, yet
there is no ordering between #1 and #3.
So, if ARG is a reference, we look though it when PARM is
not a refence. When both are references we don't change either. */
if (TREE_CODE (*arg) == REFERENCE_TYPE)
{
if (TREE_CODE (*parm) == REFERENCE_TYPE)
return 0;
*arg = TREE_TYPE (*arg);
result |= UNIFY_ALLOW_OUTER_LESS_CV_QUAL;
goto skip_arg;
}
break;
default: default:
my_friendly_abort (0); my_friendly_abort (0);
} }
...@@ -7849,6 +7889,7 @@ maybe_adjust_types_for_deduction (strict, parm, arg) ...@@ -7849,6 +7889,7 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
*arg = TYPE_MAIN_VARIANT (*arg); *arg = TYPE_MAIN_VARIANT (*arg);
} }
skip_arg:;
/* [temp.deduct.call] /* [temp.deduct.call]
If P is a cv-qualified type, the top level cv-qualifiers If P is a cv-qualified type, the top level cv-qualifiers
...@@ -7857,7 +7898,11 @@ maybe_adjust_types_for_deduction (strict, parm, arg) ...@@ -7857,7 +7898,11 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
type deduction. */ type deduction. */
*parm = TYPE_MAIN_VARIANT (*parm); *parm = TYPE_MAIN_VARIANT (*parm);
if (TREE_CODE (*parm) == REFERENCE_TYPE) if (TREE_CODE (*parm) == REFERENCE_TYPE)
*parm = TREE_TYPE (*parm); {
*parm = TREE_TYPE (*parm);
result |= UNIFY_ALLOW_OUTER_MORE_CV_QUAL;
}
return result;
} }
/* Most parms like fn_type_unification. /* Most parms like fn_type_unification.
...@@ -7902,6 +7947,10 @@ type_unification_real (tparms, targs, parms, args, subr, ...@@ -7902,6 +7947,10 @@ type_unification_real (tparms, targs, parms, args, subr,
case DEDUCE_EXACT: case DEDUCE_EXACT:
sub_strict = UNIFY_ALLOW_NONE; sub_strict = UNIFY_ALLOW_NONE;
break; break;
case DEDUCE_ORDER:
sub_strict = UNIFY_ALLOW_NONE;
break;
default: default:
my_friendly_abort (0); my_friendly_abort (0);
...@@ -7943,7 +7992,7 @@ type_unification_real (tparms, targs, parms, args, subr, ...@@ -7943,7 +7992,7 @@ type_unification_real (tparms, targs, parms, args, subr,
arg = NULL_TREE; arg = NULL_TREE;
} }
if (strict == DEDUCE_EXACT) if (strict == DEDUCE_EXACT || strict == DEDUCE_ORDER)
{ {
if (same_type_p (parm, type)) if (same_type_p (parm, type))
continue; continue;
...@@ -7976,12 +8025,16 @@ type_unification_real (tparms, targs, parms, args, subr, ...@@ -7976,12 +8025,16 @@ type_unification_real (tparms, targs, parms, args, subr,
} }
arg = TREE_TYPE (arg); arg = TREE_TYPE (arg);
} }
{
int arg_strict = sub_strict;
if (!subr)
arg_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg);
if (!subr) if (unify (tparms, targs, parm, arg, arg_strict))
maybe_adjust_types_for_deduction (strict, &parm, &arg); return 1;
}
if (unify (tparms, targs, parm, arg, sub_strict))
return 1;
/* Are we done with the interesting parms? */ /* Are we done with the interesting parms? */
if (--len == 0) if (--len == 0)
...@@ -8129,7 +8182,7 @@ try_one_overload (tparms, orig_targs, targs, parm, arg, strict, ...@@ -8129,7 +8182,7 @@ try_one_overload (tparms, orig_targs, targs, parm, arg, strict,
if (uses_template_parms (arg)) if (uses_template_parms (arg))
return 1; return 1;
maybe_adjust_types_for_deduction (strict, &parm, &arg); sub_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg);
/* We don't copy orig_targs for this because if we have already deduced /* We don't copy orig_targs for this because if we have already deduced
some template args from previous args, unify would complain when we some template args from previous args, unify would complain when we
...@@ -8413,11 +8466,11 @@ check_cv_quals_for_unify (strict, arg, parm) ...@@ -8413,11 +8466,11 @@ check_cv_quals_for_unify (strict, arg, parm)
tree arg; tree arg;
tree parm; tree parm;
{ {
if (!(strict & UNIFY_ALLOW_MORE_CV_QUAL) if (!(strict & (UNIFY_ALLOW_MORE_CV_QUAL | UNIFY_ALLOW_OUTER_MORE_CV_QUAL))
&& !at_least_as_qualified_p (arg, parm)) && !at_least_as_qualified_p (arg, parm))
return 0; return 0;
if (!(strict & UNIFY_ALLOW_LESS_CV_QUAL) if (!(strict & (UNIFY_ALLOW_LESS_CV_QUAL | UNIFY_ALLOW_OUTER_LESS_CV_QUAL))
&& !at_least_as_qualified_p (parm, arg)) && !at_least_as_qualified_p (parm, arg))
return 0; return 0;
...@@ -8448,7 +8501,13 @@ check_cv_quals_for_unify (strict, arg, parm) ...@@ -8448,7 +8501,13 @@ check_cv_quals_for_unify (strict, arg, parm)
have const qualified pointers leading up to the inner type which have const qualified pointers leading up to the inner type which
requires additional CV quals, except at the outer level, where const requires additional CV quals, except at the outer level, where const
is not required [conv.qual]. It would be normal to set this flag in is not required [conv.qual]. It would be normal to set this flag in
addition to setting UNIFY_ALLOW_MORE_CV_QUAL. */ addition to setting UNIFY_ALLOW_MORE_CV_QUAL.
UNIFY_ALLOW_OUTER_MORE_CV_QUAL:
This is the outermost level of a deduction, and PARM can be more CV
qualified at this point.
UNIFY_ALLOW_OUTER_LESS_CV_QUAL:
This is the outermost level of a deduction, and PARM can be less CV
qualified at this point. */
static int static int
unify (tparms, targs, parm, arg, strict) unify (tparms, targs, parm, arg, strict)
...@@ -8498,6 +8557,8 @@ unify (tparms, targs, parm, arg, strict) ...@@ -8498,6 +8557,8 @@ unify (tparms, targs, parm, arg, strict)
strict &= ~UNIFY_ALLOW_MORE_CV_QUAL; strict &= ~UNIFY_ALLOW_MORE_CV_QUAL;
strict &= ~UNIFY_ALLOW_OUTER_LEVEL; strict &= ~UNIFY_ALLOW_OUTER_LEVEL;
strict &= ~UNIFY_ALLOW_DERIVED; strict &= ~UNIFY_ALLOW_DERIVED;
strict &= ~UNIFY_ALLOW_OUTER_MORE_CV_QUAL;
strict &= ~UNIFY_ALLOW_OUTER_LESS_CV_QUAL;
switch (TREE_CODE (parm)) switch (TREE_CODE (parm))
{ {
...@@ -8963,6 +9024,8 @@ mark_decl_instantiated (result, extern_p) ...@@ -8963,6 +9024,8 @@ mark_decl_instantiated (result, extern_p)
/* Given two function templates PAT1 and PAT2, return: /* Given two function templates PAT1 and PAT2, return:
DEDUCE should be DEDUCE_EXACT or DEDUCE_ORDER.
1 if PAT1 is more specialized than PAT2 as described in [temp.func.order]. 1 if PAT1 is more specialized than PAT2 as described in [temp.func.order].
-1 if PAT2 is more specialized than PAT1. -1 if PAT2 is more specialized than PAT1.
0 if neither is more specialized. 0 if neither is more specialized.
...@@ -8970,18 +9033,21 @@ mark_decl_instantiated (result, extern_p) ...@@ -8970,18 +9033,21 @@ mark_decl_instantiated (result, extern_p)
LEN is passed through to fn_type_unification. */ LEN is passed through to fn_type_unification. */
int int
more_specialized (pat1, pat2, len) more_specialized (pat1, pat2, deduce, len)
tree pat1, pat2; tree pat1, pat2;
int deduce;
int len; int len;
{ {
tree targs; tree targs;
int winner = 0; int winner = 0;
targs = get_bindings_order (pat1, DECL_TEMPLATE_RESULT (pat2), len); targs = get_bindings_real (pat1, DECL_TEMPLATE_RESULT (pat2),
NULL_TREE, 0, deduce, len);
if (targs) if (targs)
--winner; --winner;
targs = get_bindings_order (pat2, DECL_TEMPLATE_RESULT (pat1), len); targs = get_bindings_real (pat2, DECL_TEMPLATE_RESULT (pat1),
NULL_TREE, 0, deduce, len);
if (targs) if (targs)
++winner; ++winner;
...@@ -9018,12 +9084,12 @@ more_specialized_class (pat1, pat2) ...@@ -9018,12 +9084,12 @@ more_specialized_class (pat1, pat2)
DECL from the function template FN, with the explicit template DECL from the function template FN, with the explicit template
arguments EXPLICIT_ARGS. If CHECK_RETTYPE is 1, the return type must arguments EXPLICIT_ARGS. If CHECK_RETTYPE is 1, the return type must
also match. Return NULL_TREE if no satisfactory arguments could be also match. Return NULL_TREE if no satisfactory arguments could be
found. LEN is passed through to fn_type_unification. */ found. DEDUCE and LEN are passed through to fn_type_unification. */
static tree static tree
get_bindings_real (fn, decl, explicit_args, check_rettype, len) get_bindings_real (fn, decl, explicit_args, check_rettype, deduce, len)
tree fn, decl, explicit_args; tree fn, decl, explicit_args;
int check_rettype, len; int check_rettype, deduce, len;
{ {
int ntparms = DECL_NTPARMS (fn); int ntparms = DECL_NTPARMS (fn);
tree targs = make_tree_vec (ntparms); tree targs = make_tree_vec (ntparms);
...@@ -9069,7 +9135,7 @@ get_bindings_real (fn, decl, explicit_args, check_rettype, len) ...@@ -9069,7 +9135,7 @@ get_bindings_real (fn, decl, explicit_args, check_rettype, len)
decl_arg_types, decl_arg_types,
(check_rettype || DECL_CONV_FN_P (fn) (check_rettype || DECL_CONV_FN_P (fn)
? TREE_TYPE (decl_type) : NULL_TREE), ? TREE_TYPE (decl_type) : NULL_TREE),
DEDUCE_EXACT, len); deduce, len);
if (i != 0) if (i != 0)
return NULL_TREE; return NULL_TREE;
...@@ -9083,7 +9149,7 @@ tree ...@@ -9083,7 +9149,7 @@ tree
get_bindings (fn, decl, explicit_args) get_bindings (fn, decl, explicit_args)
tree fn, decl, explicit_args; tree fn, decl, explicit_args;
{ {
return get_bindings_real (fn, decl, explicit_args, 1, -1); return get_bindings_real (fn, decl, explicit_args, 1, DEDUCE_EXACT, -1);
} }
/* But for resolve_overloaded_unification, we only care about the parameter /* But for resolve_overloaded_unification, we only care about the parameter
...@@ -9093,17 +9159,7 @@ static tree ...@@ -9093,17 +9159,7 @@ static tree
get_bindings_overload (fn, decl, explicit_args) get_bindings_overload (fn, decl, explicit_args)
tree fn, decl, explicit_args; tree fn, decl, explicit_args;
{ {
return get_bindings_real (fn, decl, explicit_args, 0, -1); return get_bindings_real (fn, decl, explicit_args, 0, DEDUCE_EXACT, -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 /* Return the innermost template arguments that, when applied to a
...@@ -9162,7 +9218,8 @@ most_specialized_instantiation (instantiations) ...@@ -9162,7 +9218,8 @@ most_specialized_instantiation (instantiations)
champ = instantiations; champ = instantiations;
for (fn = TREE_CHAIN (instantiations); fn; fn = TREE_CHAIN (fn)) for (fn = TREE_CHAIN (instantiations); fn; fn = TREE_CHAIN (fn))
{ {
fate = more_specialized (TREE_VALUE (champ), TREE_VALUE (fn), -1); fate = more_specialized (TREE_VALUE (champ), TREE_VALUE (fn),
DEDUCE_EXACT, -1);
if (fate == 1) if (fate == 1)
; ;
else else
...@@ -9179,7 +9236,8 @@ most_specialized_instantiation (instantiations) ...@@ -9179,7 +9236,8 @@ most_specialized_instantiation (instantiations)
for (fn = instantiations; fn && fn != champ; fn = TREE_CHAIN (fn)) for (fn = instantiations; fn && fn != champ; fn = TREE_CHAIN (fn))
{ {
fate = more_specialized (TREE_VALUE (champ), TREE_VALUE (fn), -1); fate = more_specialized (TREE_VALUE (champ), TREE_VALUE (fn),
DEDUCE_EXACT, -1);
if (fate != 1) if (fate != 1)
return error_mark_node; return error_mark_node;
} }
......
2001-01-22 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.martin/sts_partial.C: Remove XFAIL.
* g++.old-deja/g++.pt/spec35.C: New test.
* g++.old-deja/g++.pt/spec36.C: New test.
2001-01-20 Jakub Jelinek <jakub@redhat.com> 2001-01-20 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/compile/20010118-1.c: New test. * gcc.c-torture/compile/20010118-1.c: New test.
......
// excess errors test - XFAIL
// ecgs-bugs 1999-02-22 14:26 Stefan Schwarzer // ecgs-bugs 1999-02-22 14:26 Stefan Schwarzer
// sts@ica1.uni-stuttgart.de // sts@ica1.uni-stuttgart.de
// partial ordering problem in egcs <= 1.1.1 // partial ordering problem in egcs <= 1.1.1
......
// Build don't link:
//
// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 18 Jan 2001 <nathan@codesourcery.com>
// Bug 1617. We didn't resolve partial ordering properly. The std is rather
// vague about it anyway, DR 214 talks about this.
extern "C" int puts (char const *);
template <typename T> int Foo (T); // ERROR - candidate
template <typename T> int Foo (T &); // ERROR - candidate
template <typename T> int Qux (T); // ERROR - candidate
template <typename T> int Qux (T const &); // ERROR - candidate
template <typename T> int Bar (T const *const &); // ERROR - candidate
template <typename T> int Bar (T *const &); // ERROR - candidate
template <typename T> int Bar (T *); // ERROR - candidate
template <typename T> int Baz (T *const &); // ERROR - candidate
template <typename T> int Baz (T *); // ERROR - candidate
int Baz (int const *ptr, int *ptr2)
{
Baz (ptr2); // ERROR - ambiguous
Bar (ptr2); // ERROR - ambiguous
Foo (ptr2); // ERROR - ambiguous
Qux (ptr2); // ERROR - ambiguous
return 0;
}
// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 18 Jan 2001 <nathan@codesourcery.com>
// Bug 1617. We didn't resolve partial ordering properly. The std is rather
// vague about it anyway, DR 214 talks about this.
extern "C" int puts (char const *);
template <typename T> int Foo (T *) {puts (__PRETTY_FUNCTION__); return 1;}
template <typename T> int Foo (T &) {puts (__PRETTY_FUNCTION__); return 2;}
template <typename T> int Foo (T const &) {puts (__PRETTY_FUNCTION__); return 3;}
template <typename T> int Bar (T const *const &) {puts (__PRETTY_FUNCTION__); return 4;}
template <typename T> int Bar (T *const &) {puts (__PRETTY_FUNCTION__); return 5;}
template <typename T> int Bar (T *) {puts (__PRETTY_FUNCTION__); return 6;}
template <typename T> int Quux (T *const &) {puts (__PRETTY_FUNCTION__); return 7;}
template <typename T> int Quux (T const &) {puts (__PRETTY_FUNCTION__); return 8;}
int Baz (int const *ptr, int *ptr2)
{
if (Foo (ptr) != 1)
return 1;
if (Foo (ptr2) != 1)
return 2;
if (Foo (*ptr) != 3)
return 3;
if (Foo (*ptr2) != 2)
return 4;
if (Bar (ptr) != 4)
return 5;
if (Quux (ptr) != 7)
return 5;
if (Quux (ptr2) != 7)
return 6;
return 0;
}
int main ()
{
return Baz (0, 0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment