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
This commit is contained in:
parent
0bbcfbafc8
commit
62e4a75853
|
@ -1,3 +1,27 @@
|
|||
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>
|
||||
|
||||
* decl2.c (flag_vtable_thunks): Also depend on ENABLE_NEW_GXX_ABI.
|
||||
|
|
|
@ -5196,6 +5196,7 @@ joust (cand1, cand2, warn)
|
|||
else if (cand1->template && cand2->template)
|
||||
winner = more_specialized
|
||||
(TI_TEMPLATE (cand1->template), TI_TEMPLATE (cand2->template),
|
||||
DEDUCE_ORDER,
|
||||
/* Never do unification on the 'this' parameter. */
|
||||
TREE_VEC_LENGTH (cand1->convs)
|
||||
- DECL_NONSTATIC_MEMBER_FUNCTION_P (cand1->fn));
|
||||
|
|
|
@ -3209,14 +3209,15 @@ extern int function_depth;
|
|||
|
||||
/* 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
|
||||
documentation for fn_type_unification. */
|
||||
|
||||
typedef enum unification_kind_t {
|
||||
DEDUCE_CALL,
|
||||
DEDUCE_CONV,
|
||||
DEDUCE_EXACT
|
||||
DEDUCE_EXACT,
|
||||
DEDUCE_ORDER
|
||||
} unification_kind_t;
|
||||
|
||||
/* Macros for operating on a template instantation level node, represented
|
||||
|
@ -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 tree tinst_for_decl PARAMS ((void));
|
||||
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 do_decl_instantiation PARAMS ((tree, tree, tree));
|
||||
extern void do_type_instantiation PARAMS ((tree, tree, int));
|
||||
|
|
142
gcc/cp/pt.c
142
gcc/cp/pt.c
|
@ -87,6 +87,8 @@ static htab_t local_specializations;
|
|||
#define UNIFY_ALLOW_DERIVED 4
|
||||
#define UNIFY_ALLOW_INTEGER 8
|
||||
#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
|
||||
virtual, or a base class of a virtual
|
||||
|
@ -111,7 +113,7 @@ static tree coerce_template_parms PARAMS ((tree, tree, tree, int, int));
|
|||
static void tsubst_enum PARAMS ((tree, tree, tree));
|
||||
static tree add_to_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*));
|
||||
static int type_unification_real PARAMS ((tree, tree, tree, tree,
|
||||
int, unification_kind_t, int, int));
|
||||
|
@ -121,7 +123,6 @@ 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));
|
||||
|
@ -136,7 +137,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, int));
|
||||
static tree get_bindings_real PARAMS ((tree, tree, tree, int, 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));
|
||||
|
@ -7681,13 +7682,15 @@ instantiate_template (tmpl, targ_ptr)
|
|||
[temp.deduct.conv].
|
||||
|
||||
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
|
||||
ordering between specializations of function or class
|
||||
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].
|
||||
templates, as in [temp.func.order] and [temp.class.order].
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
initialized with the result of the conversion function. */
|
||||
|
||||
static void
|
||||
static int
|
||||
maybe_adjust_types_for_deduction (strict, parm, arg)
|
||||
unification_kind_t strict;
|
||||
tree* parm;
|
||||
tree* arg;
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
switch (strict)
|
||||
{
|
||||
case DEDUCE_CALL:
|
||||
|
@ -7817,8 +7822,43 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
|
|||
|
||||
case DEDUCE_EXACT:
|
||||
/* 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:
|
||||
my_friendly_abort (0);
|
||||
}
|
||||
|
@ -7849,6 +7889,7 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
|
|||
*arg = TYPE_MAIN_VARIANT (*arg);
|
||||
}
|
||||
|
||||
skip_arg:;
|
||||
/* [temp.deduct.call]
|
||||
|
||||
If P is a cv-qualified type, the top level cv-qualifiers
|
||||
|
@ -7857,7 +7898,11 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
|
|||
type deduction. */
|
||||
*parm = TYPE_MAIN_VARIANT (*parm);
|
||||
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.
|
||||
|
@ -7902,6 +7947,10 @@ type_unification_real (tparms, targs, parms, args, subr,
|
|||
case DEDUCE_EXACT:
|
||||
sub_strict = UNIFY_ALLOW_NONE;
|
||||
break;
|
||||
|
||||
case DEDUCE_ORDER:
|
||||
sub_strict = UNIFY_ALLOW_NONE;
|
||||
break;
|
||||
|
||||
default:
|
||||
my_friendly_abort (0);
|
||||
|
@ -7943,7 +7992,7 @@ type_unification_real (tparms, targs, parms, args, subr,
|
|||
arg = NULL_TREE;
|
||||
}
|
||||
|
||||
if (strict == DEDUCE_EXACT)
|
||||
if (strict == DEDUCE_EXACT || strict == DEDUCE_ORDER)
|
||||
{
|
||||
if (same_type_p (parm, type))
|
||||
continue;
|
||||
|
@ -7976,12 +8025,16 @@ type_unification_real (tparms, targs, parms, args, subr,
|
|||
}
|
||||
arg = TREE_TYPE (arg);
|
||||
}
|
||||
|
||||
{
|
||||
int arg_strict = sub_strict;
|
||||
|
||||
if (!subr)
|
||||
arg_strict |= maybe_adjust_types_for_deduction (strict, &parm, &arg);
|
||||
|
||||
if (!subr)
|
||||
maybe_adjust_types_for_deduction (strict, &parm, &arg);
|
||||
|
||||
if (unify (tparms, targs, parm, arg, sub_strict))
|
||||
return 1;
|
||||
if (unify (tparms, targs, parm, arg, arg_strict))
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Are we done with the interesting parms? */
|
||||
if (--len == 0)
|
||||
|
@ -8129,7 +8182,7 @@ try_one_overload (tparms, orig_targs, targs, parm, arg, strict,
|
|||
if (uses_template_parms (arg))
|
||||
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
|
||||
some template args from previous args, unify would complain when we
|
||||
|
@ -8413,11 +8466,11 @@ check_cv_quals_for_unify (strict, arg, parm)
|
|||
tree arg;
|
||||
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))
|
||||
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))
|
||||
return 0;
|
||||
|
||||
|
@ -8448,7 +8501,13 @@ check_cv_quals_for_unify (strict, arg, parm)
|
|||
have const qualified pointers leading up to the inner type which
|
||||
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
|
||||
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
|
||||
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_OUTER_LEVEL;
|
||||
strict &= ~UNIFY_ALLOW_DERIVED;
|
||||
strict &= ~UNIFY_ALLOW_OUTER_MORE_CV_QUAL;
|
||||
strict &= ~UNIFY_ALLOW_OUTER_LESS_CV_QUAL;
|
||||
|
||||
switch (TREE_CODE (parm))
|
||||
{
|
||||
|
@ -8963,6 +9024,8 @@ mark_decl_instantiated (result, extern_p)
|
|||
|
||||
/* 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 PAT2 is more specialized than PAT1.
|
||||
0 if neither is more specialized.
|
||||
|
@ -8970,18 +9033,21 @@ mark_decl_instantiated (result, extern_p)
|
|||
LEN is passed through to fn_type_unification. */
|
||||
|
||||
int
|
||||
more_specialized (pat1, pat2, len)
|
||||
more_specialized (pat1, pat2, deduce, len)
|
||||
tree pat1, pat2;
|
||||
int deduce;
|
||||
int len;
|
||||
{
|
||||
tree targs;
|
||||
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)
|
||||
--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)
|
||||
++winner;
|
||||
|
||||
|
@ -9018,12 +9084,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. LEN is passed through to fn_type_unification. */
|
||||
found. DEDUCE and LEN are passed through to fn_type_unification. */
|
||||
|
||||
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;
|
||||
int check_rettype, len;
|
||||
int check_rettype, deduce, len;
|
||||
{
|
||||
int ntparms = DECL_NTPARMS (fn);
|
||||
tree targs = make_tree_vec (ntparms);
|
||||
|
@ -9069,7 +9135,7 @@ get_bindings_real (fn, decl, explicit_args, check_rettype, len)
|
|||
decl_arg_types,
|
||||
(check_rettype || DECL_CONV_FN_P (fn)
|
||||
? TREE_TYPE (decl_type) : NULL_TREE),
|
||||
DEDUCE_EXACT, len);
|
||||
deduce, len);
|
||||
|
||||
if (i != 0)
|
||||
return NULL_TREE;
|
||||
|
@ -9083,7 +9149,7 @@ tree
|
|||
get_bindings (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
|
||||
|
@ -9093,17 +9159,7 @@ static tree
|
|||
get_bindings_overload (fn, decl, explicit_args)
|
||||
tree fn, decl, explicit_args;
|
||||
{
|
||||
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 get_bindings_real (fn, decl, explicit_args, 0, DEDUCE_EXACT, -1);
|
||||
}
|
||||
|
||||
/* Return the innermost template arguments that, when applied to a
|
||||
|
@ -9162,7 +9218,8 @@ most_specialized_instantiation (instantiations)
|
|||
champ = instantiations;
|
||||
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)
|
||||
;
|
||||
else
|
||||
|
@ -9179,7 +9236,8 @@ most_specialized_instantiation (instantiations)
|
|||
|
||||
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)
|
||||
return error_mark_node;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
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>
|
||||
|
||||
* gcc.c-torture/compile/20010118-1.c: New test.
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// excess errors test - XFAIL
|
||||
// ecgs-bugs 1999-02-22 14:26 Stefan Schwarzer
|
||||
// sts@ica1.uni-stuttgart.de
|
||||
// partial ordering problem in egcs <= 1.1.1
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
// 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;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
// 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);
|
||||
}
|
Loading…
Reference in New Issue