Commit 3d2f6864 by Nathan Froyd Committed by Jason Merrill

re PR c++/45329 (When printing a list of candidate functions, explain why each…

re PR c++/45329 (When printing a list of candidate functions, explain why each function failed to match.)

	PR c++/45329
	PR c++/48934
	* cp-tree.h (fn_type_unification): Add `bool' parameter.
	* pt.c (enum template_base_result): Define.
	(unify_success, unify_unknown): Define.
	(unify_parameter_deduction_failure): Define.
	(unify_invalid, unify_cv_qual_mismatch, unify_type_mismatch): Define.
	(unify_parameter_pack_mismatch): Define.
	(unify_parameter_pack_inconsistent): Define.
	(unify_ptrmem_cst_mismatch, unify_vla_arg): Define.
	(unify_expression_unequal, unify_inconsistency): Define.
	(unify_method_type_error, unify_arity): Likewise.
	(unify_too_many_parameters, unify_too_few_parameters): Define.
	(unify_arg_conversion, unify_no_common_base): Define.
	(unify_illformed_ptrmem_cst_expr): Define.
	(unify_substitution_failure): Define.
	(unify_inconsistent_template_template_parameters): Define.
	(unify_template_deduction_failure): Define.
	(unify_template_argument_mismatch): Define.
	(unify_overload_resolution_failure): Define.
	(comp_template_args_with_info): New function, split out from...
	(comp_template_args): ...here.	Call it.
	(deduction_tsubst_fntype): Add `complain' parameter'.  Pass it
	to tsubst.
	(unify): Add `explain_p' parameter.  Pass to all relevant calls.
	Call above status functions when appropriate.
	(resolve_overloaded_unification, try_one_overload): Likewise.
	(type_unification, type_unification_real): Likewise.
	(unify_pack_expansion): Likewise.
	(get_template_base, try_class_unification): Likewise.
	(get_bindings, more_specialized_fn): Pass false to unification
	calls.
	(get_class_bindings, do_auto_deduction): Likewise.
	(convert_nontype_argument): Likewise.
	(fn_type_unification): Likewise.  Pass tf_warning_or_error if
	explain_p.
	(get_template_base): Add `explain_p' parameter and pass it to
	try_class_unification.	Return an enum template_base_result.
	* class.c (resolve_address_of_overloaded_function): Pass false to
	fn_type_unification.
	* call.c (enum rejection_reason_code): Add new codes.
	(struct rejection_reason): Add template_unification field.
	Add template_instantiation field.
	(template_unification_rejection): Define.
	(template_unification_error_rejection): Define.
	(template_instantiation_rejection): Define.
	(invalid_copy_with_fn_template_rejection): Define.
	(add_template_candidate): Pass false to unify.
	Provide more rejection reasons when possible.
	(print_template_unification_rejection): Define.
	(print_arity_rejection): Define, split out from...
	(print_z_candidate): ...here.  Add cases for new rejection
	reasons.

Co-Authored-By: Jason Merrill <jason@redhat.com>

From-SVN: r176365
parent c6f4a801
2011-07-16 Nathan Froyd <froydnj@codesourcery.com>
Jason Merrill <jason@redhat.com>
PR c++/45329
PR c++/48934
* cp-tree.h (fn_type_unification): Add `bool' parameter.
* pt.c (enum template_base_result): Define.
(unify_success, unify_unknown): Define.
(unify_parameter_deduction_failure): Define.
(unify_invalid, unify_cv_qual_mismatch, unify_type_mismatch): Define.
(unify_parameter_pack_mismatch): Define.
(unify_parameter_pack_inconsistent): Define.
(unify_ptrmem_cst_mismatch, unify_vla_arg): Define.
(unify_expression_unequal, unify_inconsistency): Define.
(unify_method_type_error, unify_arity): Likewise.
(unify_too_many_parameters, unify_too_few_parameters): Define.
(unify_arg_conversion, unify_no_common_base): Define.
(unify_illformed_ptrmem_cst_expr): Define.
(unify_substitution_failure): Define.
(unify_inconsistent_template_template_parameters): Define.
(unify_template_deduction_failure): Define.
(unify_template_argument_mismatch): Define.
(unify_overload_resolution_failure): Define.
(comp_template_args_with_info): New function, split out from...
(comp_template_args): ...here. Call it.
(deduction_tsubst_fntype): Add `complain' parameter'. Pass it
to tsubst.
(unify): Add `explain_p' parameter. Pass to all relevant calls.
Call above status functions when appropriate.
(resolve_overloaded_unification, try_one_overload): Likewise.
(type_unification, type_unification_real): Likewise.
(unify_pack_expansion): Likewise.
(get_template_base, try_class_unification): Likewise.
(get_bindings, more_specialized_fn): Pass false to unification
calls.
(get_class_bindings, do_auto_deduction): Likewise.
(convert_nontype_argument): Likewise.
(fn_type_unification): Likewise. Pass tf_warning_or_error if
explain_p.
(get_template_base): Add `explain_p' parameter and pass it to
try_class_unification. Return an enum template_base_result.
* class.c (resolve_address_of_overloaded_function): Pass false to
fn_type_unification.
* call.c (enum rejection_reason_code): Add new codes.
(struct rejection_reason): Add template_unification field.
Add template_instantiation field.
(template_unification_rejection): Define.
(template_unification_error_rejection): Define.
(template_instantiation_rejection): Define.
(invalid_copy_with_fn_template_rejection): Define.
(add_template_candidate): Pass false to unify.
Provide more rejection reasons when possible.
(print_template_unification_rejection): Define.
(print_arity_rejection): Define, split out from...
(print_z_candidate): ...here. Add cases for new rejection
reasons.
2011-07-15 Jason Merrill <jason@redhat.com> 2011-07-15 Jason Merrill <jason@redhat.com>
* Make-lang.in (check-g++-strict-gc): New. * Make-lang.in (check-g++-strict-gc): New.
......
...@@ -434,7 +434,10 @@ enum rejection_reason_code { ...@@ -434,7 +434,10 @@ enum rejection_reason_code {
rr_arity, rr_arity,
rr_explicit_conversion, rr_explicit_conversion,
rr_arg_conversion, rr_arg_conversion,
rr_bad_arg_conversion rr_bad_arg_conversion,
rr_template_unification,
rr_template_instantiation,
rr_invalid_copy
}; };
struct conversion_info { struct conversion_info {
...@@ -462,6 +465,24 @@ struct rejection_reason { ...@@ -462,6 +465,24 @@ struct rejection_reason {
struct conversion_info conversion; struct conversion_info conversion;
/* Same, but for bad argument conversions. */ /* Same, but for bad argument conversions. */
struct conversion_info bad_conversion; struct conversion_info bad_conversion;
/* Information about template unification failures. These are the
parameters passed to fn_type_unification. */
struct {
tree tmpl;
tree explicit_targs;
tree targs;
const tree *args;
unsigned int nargs;
tree return_type;
unification_kind_t strict;
int flags;
} template_unification;
/* Information about template instantiation failures. These are the
parameters passed to instantiate_template. */
struct {
tree tmpl;
tree targs;
} template_instantiation;
} u; } u;
}; };
...@@ -622,6 +643,50 @@ explicit_conversion_rejection (tree from, tree to) ...@@ -622,6 +643,50 @@ explicit_conversion_rejection (tree from, tree to)
return r; return r;
} }
static struct rejection_reason *
template_unification_rejection (tree tmpl, tree explicit_targs, tree targs,
const tree *args, unsigned int nargs,
tree return_type, unification_kind_t strict,
int flags)
{
size_t args_n_bytes = sizeof (*args) * nargs;
tree *args1 = (tree *) conversion_obstack_alloc (args_n_bytes);
struct rejection_reason *r = alloc_rejection (rr_template_unification);
r->u.template_unification.tmpl = tmpl;
r->u.template_unification.explicit_targs = explicit_targs;
r->u.template_unification.targs = targs;
/* Copy args to our own storage. */
memcpy (args1, args, args_n_bytes);
r->u.template_unification.args = args1;
r->u.template_unification.nargs = nargs;
r->u.template_unification.return_type = return_type;
r->u.template_unification.strict = strict;
r->u.template_unification.flags = flags;
return r;
}
static struct rejection_reason *
template_unification_error_rejection (void)
{
return alloc_rejection (rr_template_unification);
}
static struct rejection_reason *
template_instantiation_rejection (tree tmpl, tree targs)
{
struct rejection_reason *r = alloc_rejection (rr_template_instantiation);
r->u.template_instantiation.tmpl = tmpl;
r->u.template_instantiation.targs = targs;
return r;
}
static struct rejection_reason *
invalid_copy_with_fn_template_rejection (void)
{
struct rejection_reason *r = alloc_rejection (rr_invalid_copy);
return r;
}
/* Dynamically allocate a conversion. */ /* Dynamically allocate a conversion. */
static conversion * static conversion *
...@@ -2859,6 +2924,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, ...@@ -2859,6 +2924,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
int i; int i;
tree fn; tree fn;
struct rejection_reason *reason = NULL; struct rejection_reason *reason = NULL;
int errs;
/* We don't do deduction on the in-charge parameter, the VTT /* We don't do deduction on the in-charge parameter, the VTT
parameter or 'this'. */ parameter or 'this'. */
...@@ -2901,17 +2967,31 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, ...@@ -2901,17 +2967,31 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
} }
gcc_assert (ia == nargs_without_in_chrg); gcc_assert (ia == nargs_without_in_chrg);
errs = errorcount+sorrycount;
i = fn_type_unification (tmpl, explicit_targs, targs, i = fn_type_unification (tmpl, explicit_targs, targs,
args_without_in_chrg, args_without_in_chrg,
nargs_without_in_chrg, nargs_without_in_chrg,
return_type, strict, flags); return_type, strict, flags, false);
if (i != 0) if (i != 0)
goto fail; {
/* Don't repeat unification later if it already resulted in errors. */
if (errorcount+sorrycount == errs)
reason = template_unification_rejection (tmpl, explicit_targs,
targs, args_without_in_chrg,
nargs_without_in_chrg,
return_type, strict, flags);
else
reason = template_unification_error_rejection ();
goto fail;
}
fn = instantiate_template (tmpl, targs, tf_none); fn = instantiate_template (tmpl, targs, tf_none);
if (fn == error_mark_node) if (fn == error_mark_node)
goto fail; {
reason = template_instantiation_rejection (tmpl, targs);
goto fail;
}
/* In [class.copy]: /* In [class.copy]:
...@@ -2940,7 +3020,10 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, ...@@ -2940,7 +3020,10 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn); tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn);
if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)), if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)),
ctype)) ctype))
goto fail; {
reason = invalid_copy_with_fn_template_rejection ();
goto fail;
}
} }
if (obj != NULL_TREE) if (obj != NULL_TREE)
...@@ -3108,6 +3191,18 @@ print_conversion_rejection (location_t loc, struct conversion_info *info) ...@@ -3108,6 +3191,18 @@ print_conversion_rejection (location_t loc, struct conversion_info *info)
info->n_arg+1, info->from_type, info->to_type); info->n_arg+1, info->from_type, info->to_type);
} }
/* Print information about a candidate with WANT parameters and we found
HAVE. */
static void
print_arity_information (location_t loc, unsigned int have, unsigned int want)
{
inform_n (loc, want,
" candidate expects %d argument, %d provided",
" candidate expects %d arguments, %d provided",
want, have);
}
/* Print information about one overload candidate CANDIDATE. MSGSTR /* Print information about one overload candidate CANDIDATE. MSGSTR
is the text to print before the candidate itself. is the text to print before the candidate itself.
...@@ -3154,10 +3249,8 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate) ...@@ -3154,10 +3249,8 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate)
switch (r->code) switch (r->code)
{ {
case rr_arity: case rr_arity:
inform_n (loc, r->u.arity.expected, print_arity_information (loc, r->u.arity.actual,
" candidate expects %d argument, %d provided", r->u.arity.expected);
" candidate expects %d arguments, %d provided",
r->u.arity.expected, r->u.arity.actual);
break; break;
case rr_arg_conversion: case rr_arg_conversion:
print_conversion_rejection (loc, &r->u.conversion); print_conversion_rejection (loc, &r->u.conversion);
...@@ -3171,6 +3264,39 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate) ...@@ -3171,6 +3264,39 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate)
"conversion", r->u.conversion.from_type, "conversion", r->u.conversion.from_type,
r->u.conversion.to_type); r->u.conversion.to_type);
break; break;
case rr_template_unification:
/* We use template_unification_error_rejection if unification caused
actual non-SFINAE errors, in which case we don't need to repeat
them here. */
if (r->u.template_unification.tmpl == NULL_TREE)
{
inform (loc, " substitution of deduced template arguments "
"resulted in errors seen above");
break;
}
/* Re-run template unification with diagnostics. */
inform (loc, " template argument deduction/substitution failed:");
fn_type_unification (r->u.template_unification.tmpl,
r->u.template_unification.explicit_targs,
r->u.template_unification.targs,
r->u.template_unification.args,
r->u.template_unification.nargs,
r->u.template_unification.return_type,
r->u.template_unification.strict,
r->u.template_unification.flags,
true);
break;
case rr_template_instantiation:
/* Re-run template instantiation with diagnostics. */
instantiate_template (r->u.template_instantiation.tmpl,
r->u.template_instantiation.targs,
tf_warning_or_error);
break;
case rr_invalid_copy:
inform (loc,
" a constructor taking a single argument of its own "
"class type is invalid");
break;
case rr_none: case rr_none:
default: default:
/* This candidate didn't have any issues or we failed to /* This candidate didn't have any issues or we failed to
......
...@@ -6570,7 +6570,7 @@ resolve_address_of_overloaded_function (tree target_type, ...@@ -6570,7 +6570,7 @@ resolve_address_of_overloaded_function (tree target_type,
targs = make_tree_vec (DECL_NTPARMS (fn)); targs = make_tree_vec (DECL_NTPARMS (fn));
if (fn_type_unification (fn, explicit_targs, targs, args, nargs, if (fn_type_unification (fn, explicit_targs, targs, args, nargs,
target_ret_type, DEDUCE_EXACT, target_ret_type, DEDUCE_EXACT,
LOOKUP_NORMAL)) LOOKUP_NORMAL, false))
/* Argument deduction failed. */ /* Argument deduction failed. */
continue; continue;
......
...@@ -5161,7 +5161,8 @@ extern tree instantiate_class_template (tree); ...@@ -5161,7 +5161,8 @@ extern tree instantiate_class_template (tree);
extern tree instantiate_template (tree, tree, tsubst_flags_t); extern tree instantiate_template (tree, tree, tsubst_flags_t);
extern int fn_type_unification (tree, tree, tree, extern int fn_type_unification (tree, tree, tree,
const tree *, unsigned int, const tree *, unsigned int,
tree, unification_kind_t, int); tree, unification_kind_t, int,
bool);
extern void mark_decl_instantiated (tree, int); extern void mark_decl_instantiated (tree, int);
extern int more_specialized_fn (tree, tree, int); extern int more_specialized_fn (tree, tree, int);
extern void do_decl_instantiation (tree, tree); extern void do_decl_instantiation (tree, tree);
......
...@@ -109,15 +109,22 @@ static GTY(()) VEC(tree,gc) *canonical_template_parms; ...@@ -109,15 +109,22 @@ static GTY(()) VEC(tree,gc) *canonical_template_parms;
#define UNIFY_ALLOW_OUTER_MORE_CV_QUAL 32 #define UNIFY_ALLOW_OUTER_MORE_CV_QUAL 32
#define UNIFY_ALLOW_OUTER_LESS_CV_QUAL 64 #define UNIFY_ALLOW_OUTER_LESS_CV_QUAL 64
enum template_base_result {
tbr_incomplete_type,
tbr_ambiguous_baseclass,
tbr_success
};
static void push_access_scope (tree); static void push_access_scope (tree);
static void pop_access_scope (tree); static void pop_access_scope (tree);
static void push_deduction_access_scope (tree); static void push_deduction_access_scope (tree);
static void pop_deduction_access_scope (tree); static void pop_deduction_access_scope (tree);
static bool resolve_overloaded_unification (tree, tree, tree, tree, static bool resolve_overloaded_unification (tree, tree, tree, tree,
unification_kind_t, int); unification_kind_t, int,
bool);
static int try_one_overload (tree, tree, tree, tree, tree, static int try_one_overload (tree, tree, tree, tree, tree,
unification_kind_t, int, bool); unification_kind_t, int, bool, bool);
static int unify (tree, tree, tree, tree, int); static int unify (tree, tree, tree, tree, int, bool);
static void add_pending_template (tree); static void add_pending_template (tree);
static tree reopen_tinst_level (struct tinst_level *); static tree reopen_tinst_level (struct tinst_level *);
static tree tsubst_initializer_list (tree, tree); static tree tsubst_initializer_list (tree, tree);
...@@ -131,7 +138,8 @@ static bool check_instantiated_args (tree, tree, tsubst_flags_t); ...@@ -131,7 +138,8 @@ static bool check_instantiated_args (tree, tree, tsubst_flags_t);
static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*, static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*,
tree); tree);
static int type_unification_real (tree, tree, tree, const tree *, static int type_unification_real (tree, tree, tree, const tree *,
unsigned int, int, unification_kind_t, int); unsigned int, int, unification_kind_t, int,
bool);
static void note_template_header (int); static void note_template_header (int);
static tree convert_nontype_argument_function (tree, tree); static tree convert_nontype_argument_function (tree, tree);
static tree convert_nontype_argument (tree, tree, tsubst_flags_t); static tree convert_nontype_argument (tree, tree, tsubst_flags_t);
...@@ -156,7 +164,8 @@ static tree get_bindings (tree, tree, tree, bool); ...@@ -156,7 +164,8 @@ static tree get_bindings (tree, tree, tree, bool);
static int template_decl_level (tree); static int template_decl_level (tree);
static int check_cv_quals_for_unify (int, tree, tree); static int check_cv_quals_for_unify (int, tree, tree);
static void template_parm_level_and_index (tree, int*, int*); static void template_parm_level_and_index (tree, int*, int*);
static int unify_pack_expansion (tree, tree, tree, tree, int, bool, bool); static int unify_pack_expansion (tree, tree, tree,
tree, int, bool, bool, bool);
static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree);
static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree); static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree);
static tree tsubst_template_parms (tree, tree, tsubst_flags_t); static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
...@@ -168,8 +177,9 @@ static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree); ...@@ -168,8 +177,9 @@ static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
static bool check_specialization_scope (void); static bool check_specialization_scope (void);
static tree process_partial_specialization (tree); static tree process_partial_specialization (tree);
static void set_current_access_from_decl (tree); static void set_current_access_from_decl (tree);
static tree get_template_base (tree, tree, tree, tree); static enum template_base_result get_template_base (tree, tree, tree, tree,
static tree try_class_unification (tree, tree, tree, tree); bool , tree *);
static tree try_class_unification (tree, tree, tree, tree, bool);
static int coerce_template_template_parms (tree, tree, tsubst_flags_t, static int coerce_template_template_parms (tree, tree, tsubst_flags_t,
tree, tree); tree, tree);
static bool template_template_parm_bindings_ok_p (tree, tree); static bool template_template_parm_bindings_ok_p (tree, tree);
...@@ -5267,6 +5277,211 @@ has_value_dependent_address (tree op) ...@@ -5267,6 +5277,211 @@ has_value_dependent_address (tree op)
return false; return false;
} }
/* The next set of functions are used for providing helpful explanatory
diagnostics for failed overload resolution. Their messages should be
indented by two spaces for consistency with the messages in
call.c */
static int
unify_success (bool explain_p ATTRIBUTE_UNUSED)
{
return 0;
}
static int
unify_parameter_deduction_failure (bool explain_p, tree parm)
{
if (explain_p)
inform (input_location,
" couldn't deduce template parameter %qD", parm);
return 1;
}
static int
unify_invalid (bool explain_p ATTRIBUTE_UNUSED)
{
return 1;
}
static int
unify_cv_qual_mismatch (bool explain_p, tree parm, tree arg)
{
if (explain_p)
inform (input_location,
" types %qT and %qT have incompatible cv-qualifiers",
parm, arg);
return 1;
}
static int
unify_type_mismatch (bool explain_p, tree parm, tree arg)
{
if (explain_p)
inform (input_location, " mismatched types %qT and %qT", parm, arg);
return 1;
}
static int
unify_parameter_pack_mismatch (bool explain_p, tree parm, tree arg)
{
if (explain_p)
inform (input_location,
" template parameter %qD is not a parameter pack, but "
"argument %qD is",
parm, arg);
return 1;
}
static int
unify_ptrmem_cst_mismatch (bool explain_p, tree parm, tree arg)
{
if (explain_p)
inform (input_location,
" template argument %qE does not match "
"pointer-to-member constant %qE",
arg, parm);
return 1;
}
static int
unify_expression_unequal (bool explain_p, tree parm, tree arg)
{
if (explain_p)
inform (input_location, " %qE is not equivalent to %qE", parm, arg);
return 1;
}
static int
unify_parameter_pack_inconsistent (bool explain_p, tree old_arg, tree new_arg)
{
if (explain_p)
inform (input_location,
" inconsistent parameter pack deduction with %qT and %qT",
old_arg, new_arg);
return 1;
}
static int
unify_inconsistency (bool explain_p, tree parm, tree first, tree second)
{
if (explain_p)
inform (input_location,
" deduced conflicting types for parameter %qT (%qT and %qT)",
parm, first, second);
return 1;
}
static int
unify_vla_arg (bool explain_p, tree arg)
{
if (explain_p)
inform (input_location,
" variable-sized array type %qT is not "
"a valid template argument",
arg);
return 1;
}
static int
unify_method_type_error (bool explain_p, tree arg)
{
if (explain_p)
inform (input_location,
" member function type %qT is not a valid template argument",
arg);
return 1;
}
static int
unify_arity (bool explain_p, int have, int wanted)
{
if (explain_p)
inform_n (input_location, wanted,
" candidate expects %d argument, %d provided",
" candidate expects %d arguments, %d provided",
wanted, have);
return 1;
}
static int
unify_too_many_arguments (bool explain_p, int have, int wanted)
{
return unify_arity (explain_p, have, wanted);
}
static int
unify_too_few_arguments (bool explain_p, int have, int wanted)
{
return unify_arity (explain_p, have, wanted);
}
static int
unify_arg_conversion (bool explain_p, tree to_type,
tree from_type, tree arg)
{
if (explain_p)
inform (input_location, " cannot convert %qE (type %qT) to type %qT",
arg, from_type, to_type);
return 1;
}
static int
unify_no_common_base (bool explain_p, enum template_base_result r,
tree parm, tree arg)
{
if (explain_p)
switch (r)
{
case tbr_ambiguous_baseclass:
inform (input_location, " %qT is an ambiguous base class of %qT",
arg, parm);
break;
default:
inform (input_location, " %qT is not derived from %qT", arg, parm);
break;
}
return 1;
}
static int
unify_inconsistent_template_template_parameters (bool explain_p)
{
if (explain_p)
inform (input_location,
" template parameters of a template template argument are "
"inconsistent with other deduced template arguments");
return 1;
}
static int
unify_template_deduction_failure (bool explain_p, tree parm, tree arg)
{
if (explain_p)
inform (input_location,
" can't deduce a template for %qT from non-template type %qT",
parm, arg);
return 1;
}
static int
unify_template_argument_mismatch (bool explain_p, tree parm, tree arg)
{
if (explain_p)
inform (input_location,
" template argument %qE does not match %qD", arg, parm);
return 1;
}
static int
unify_overload_resolution_failure (bool explain_p, tree arg)
{
if (explain_p)
inform (input_location,
" could not resolve address from overloaded function %qE",
arg);
return 1;
}
/* Attempt to convert the non-type template parameter EXPR to the /* Attempt to convert the non-type template parameter EXPR to the
indicated TYPE. If the conversion is successful, return the indicated TYPE. If the conversion is successful, return the
converted value. If the conversion is unsuccessful, return converted value. If the conversion is unsuccessful, return
...@@ -6550,11 +6765,13 @@ template_args_equal (tree ot, tree nt) ...@@ -6550,11 +6765,13 @@ template_args_equal (tree ot, tree nt)
return cp_tree_equal (ot, nt); return cp_tree_equal (ot, nt);
} }
/* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets /* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets of
of template arguments. Returns 0 otherwise. */ template arguments. Returns 0 otherwise, and updates OLDARG_PTR and
NEWARG_PTR with the offending arguments if they are non-NULL. */
int static int
comp_template_args (tree oldargs, tree newargs) comp_template_args_with_info (tree oldargs, tree newargs,
tree *oldarg_ptr, tree *newarg_ptr)
{ {
int i; int i;
...@@ -6567,11 +6784,26 @@ comp_template_args (tree oldargs, tree newargs) ...@@ -6567,11 +6784,26 @@ comp_template_args (tree oldargs, tree newargs)
tree ot = TREE_VEC_ELT (oldargs, i); tree ot = TREE_VEC_ELT (oldargs, i);
if (! template_args_equal (ot, nt)) if (! template_args_equal (ot, nt))
return 0; {
if (oldarg_ptr != NULL)
*oldarg_ptr = ot;
if (newarg_ptr != NULL)
*newarg_ptr = nt;
return 0;
}
} }
return 1; return 1;
} }
/* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets
of template arguments. Returns 0 otherwise. */
int
comp_template_args (tree oldargs, tree newargs)
{
return comp_template_args_with_info (oldargs, newargs, NULL, NULL);
}
static void static void
add_pending_template (tree d) add_pending_template (tree d)
{ {
...@@ -13724,7 +13956,7 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain) ...@@ -13724,7 +13956,7 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
This is, of course, not reentrant. */ This is, of course, not reentrant. */
static tree static tree
deduction_tsubst_fntype (tree fn, tree targs) deduction_tsubst_fntype (tree fn, tree targs, tsubst_flags_t complain)
{ {
static bool excessive_deduction_depth; static bool excessive_deduction_depth;
static int deduction_depth; static int deduction_depth;
...@@ -13748,7 +13980,7 @@ deduction_tsubst_fntype (tree fn, tree targs) ...@@ -13748,7 +13980,7 @@ deduction_tsubst_fntype (tree fn, tree targs)
input_location = DECL_SOURCE_LOCATION (fn); input_location = DECL_SOURCE_LOCATION (fn);
++deduction_depth; ++deduction_depth;
push_deduction_access_scope (fn); push_deduction_access_scope (fn);
r = tsubst (fntype, targs, tf_none, NULL_TREE); r = tsubst (fntype, targs, complain, NULL_TREE);
pop_deduction_access_scope (fn); pop_deduction_access_scope (fn);
--deduction_depth; --deduction_depth;
...@@ -13961,7 +14193,8 @@ fn_type_unification (tree fn, ...@@ -13961,7 +14193,8 @@ fn_type_unification (tree fn,
unsigned int nargs, unsigned int nargs,
tree return_type, tree return_type,
unification_kind_t strict, unification_kind_t strict,
int flags) int flags,
bool explain_p)
{ {
tree parms; tree parms;
tree fntype; tree fntype;
...@@ -13996,12 +14229,15 @@ fn_type_unification (tree fn, ...@@ -13996,12 +14229,15 @@ fn_type_unification (tree fn,
bool incomplete = false; bool incomplete = false;
if (explicit_targs == error_mark_node) if (explicit_targs == error_mark_node)
return 1; return unify_invalid (explain_p);
converted_args converted_args
= (coerce_template_parms (tparms, explicit_targs, NULL_TREE, tf_none, = (coerce_template_parms (tparms, explicit_targs, NULL_TREE,
/*require_all_args=*/false, (explain_p
/*use_default_args=*/false)); ? tf_warning_or_error
: tf_none),
/*require_all_args=*/false,
/*use_default_args=*/false));
if (converted_args == error_mark_node) if (converted_args == error_mark_node)
return 1; return 1;
...@@ -14060,7 +14296,10 @@ fn_type_unification (tree fn, ...@@ -14060,7 +14296,10 @@ fn_type_unification (tree fn,
incomplete = NUM_TMPL_ARGS (explicit_targs) != NUM_TMPL_ARGS (targs); incomplete = NUM_TMPL_ARGS (explicit_targs) != NUM_TMPL_ARGS (targs);
processing_template_decl += incomplete; processing_template_decl += incomplete;
fntype = deduction_tsubst_fntype (fn, converted_args); fntype = deduction_tsubst_fntype (fn, converted_args,
(explain_p
? tf_warning_or_error
: tf_none));
processing_template_decl -= incomplete; processing_template_decl -= incomplete;
if (fntype == error_mark_node) if (fntype == error_mark_node)
...@@ -14092,7 +14331,7 @@ fn_type_unification (tree fn, ...@@ -14092,7 +14331,7 @@ fn_type_unification (tree fn,
event. */ event. */
result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn), result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
targs, parms, args, nargs, /*subr=*/0, targs, parms, args, nargs, /*subr=*/0,
strict, flags); strict, flags, explain_p);
/* Now that we have bindings for all of the template arguments, /* Now that we have bindings for all of the template arguments,
ensure that the arguments deduced for the template template ensure that the arguments deduced for the template template
...@@ -14118,7 +14357,7 @@ fn_type_unification (tree fn, ...@@ -14118,7 +14357,7 @@ fn_type_unification (tree fn,
if (result == 0 if (result == 0
&& !template_template_parm_bindings_ok_p && !template_template_parm_bindings_ok_p
(DECL_INNERMOST_TEMPLATE_PARMS (fn), targs)) (DECL_INNERMOST_TEMPLATE_PARMS (fn), targs))
return 1; return unify_inconsistent_template_template_parameters (explain_p);
if (result == 0) if (result == 0)
/* All is well so far. Now, check: /* All is well so far. Now, check:
...@@ -14131,7 +14370,10 @@ fn_type_unification (tree fn, ...@@ -14131,7 +14370,10 @@ fn_type_unification (tree fn,
substitution results in an invalid type, as described above, substitution results in an invalid type, as described above,
type deduction fails. */ type deduction fails. */
{ {
tree substed = deduction_tsubst_fntype (fn, targs); tree substed = deduction_tsubst_fntype (fn, targs,
(explain_p
? tf_warning_or_error
: tf_none));
if (substed == error_mark_node) if (substed == error_mark_node)
return 1; return 1;
...@@ -14148,7 +14390,8 @@ fn_type_unification (tree fn, ...@@ -14148,7 +14390,8 @@ fn_type_unification (tree fn,
sarg = tree_cons (NULL_TREE, TREE_TYPE (substed), sarg); sarg = tree_cons (NULL_TREE, TREE_TYPE (substed), sarg);
for (i = 0; i < nargs && sarg; ++i, sarg = TREE_CHAIN (sarg)) for (i = 0; i < nargs && sarg; ++i, sarg = TREE_CHAIN (sarg))
if (!same_type_p (args[i], TREE_VALUE (sarg))) if (!same_type_p (args[i], TREE_VALUE (sarg)))
return 1; return unify_type_mismatch (explain_p, args[i],
TREE_VALUE (sarg));
} }
} }
...@@ -14279,7 +14522,8 @@ type_unification_real (tree tparms, ...@@ -14279,7 +14522,8 @@ type_unification_real (tree tparms,
unsigned int xnargs, unsigned int xnargs,
int subr, int subr,
unification_kind_t strict, unification_kind_t strict,
int flags) int flags,
bool explain_p)
{ {
tree parm, arg, arg_expr; tree parm, arg, arg_expr;
int i; int i;
...@@ -14350,7 +14594,7 @@ type_unification_real (tree tparms, ...@@ -14350,7 +14594,7 @@ type_unification_real (tree tparms,
arg_expr = NULL; arg_expr = NULL;
if (arg == error_mark_node) if (arg == error_mark_node)
return 1; return unify_invalid (explain_p);
if (arg == unknown_type_node) if (arg == unknown_type_node)
/* We can't deduce anything from this, but we might get all the /* We can't deduce anything from this, but we might get all the
template args from other function args. */ template args from other function args. */
...@@ -14376,7 +14620,10 @@ type_unification_real (tree tparms, ...@@ -14376,7 +14620,10 @@ type_unification_real (tree tparms,
flags)) flags))
continue; continue;
return 1; if (strict == DEDUCE_EXACT)
return unify_type_mismatch (explain_p, parm, arg);
else
return unify_arg_conversion (explain_p, parm, type, arg);
} }
if (!TYPE_P (arg)) if (!TYPE_P (arg))
...@@ -14392,15 +14639,15 @@ type_unification_real (tree tparms, ...@@ -14392,15 +14639,15 @@ type_unification_real (tree tparms,
function templates and at most one of a set of function templates and at most one of a set of
overloaded functions provides a unique match. */ overloaded functions provides a unique match. */
if (resolve_overloaded_unification if (resolve_overloaded_unification
(tparms, targs, parm, arg, strict, sub_strict)) (tparms, targs, parm, arg, strict, sub_strict, explain_p))
continue; continue;
return 1; return unify_overload_resolution_failure (explain_p, arg);
} }
arg_expr = arg; arg_expr = arg;
arg = unlowered_expr_type (arg); arg = unlowered_expr_type (arg);
if (arg == error_mark_node) if (arg == error_mark_node)
return 1; return unify_invalid (explain_p);
} }
{ {
...@@ -14412,7 +14659,9 @@ type_unification_real (tree tparms, ...@@ -14412,7 +14659,9 @@ type_unification_real (tree tparms,
if (arg == init_list_type_node && arg_expr) if (arg == init_list_type_node && arg_expr)
arg = arg_expr; arg = arg_expr;
if (unify (tparms, targs, parm, arg, arg_strict)) if (unify (tparms, targs, parm, arg, arg_strict, explain_p))
/* If unification failed, the recursive call will have updated
UI appropriately. */
return 1; return 1;
} }
} }
...@@ -14434,7 +14683,7 @@ type_unification_real (tree tparms, ...@@ -14434,7 +14683,7 @@ type_unification_real (tree tparms,
/* Copy the parameter into parmvec. */ /* Copy the parameter into parmvec. */
TREE_VEC_ELT (parmvec, 0) = TREE_VALUE (parms); TREE_VEC_ELT (parmvec, 0) = TREE_VALUE (parms);
if (unify_pack_expansion (tparms, targs, parmvec, argvec, strict, if (unify_pack_expansion (tparms, targs, parmvec, argvec, strict,
/*call_args_p=*/true, /*subr=*/subr)) /*call_args_p=*/true, /*subr=*/subr, explain_p))
return 1; return 1;
/* Advance to the end of the list of parameters. */ /* Advance to the end of the list of parameters. */
...@@ -14444,11 +14693,20 @@ type_unification_real (tree tparms, ...@@ -14444,11 +14693,20 @@ type_unification_real (tree tparms,
/* Fail if we've reached the end of the parm list, and more args /* Fail if we've reached the end of the parm list, and more args
are present, and the parm list isn't variadic. */ are present, and the parm list isn't variadic. */
if (ia < nargs && parms == void_list_node) if (ia < nargs && parms == void_list_node)
return 1; return unify_too_many_arguments (explain_p, nargs, ia);
/* Fail if parms are left and they don't have default values. */ /* Fail if parms are left and they don't have default values. */
if (parms && parms != void_list_node if (parms && parms != void_list_node
&& TREE_PURPOSE (parms) == NULL_TREE) && TREE_PURPOSE (parms) == NULL_TREE)
return 1; {
unsigned int count = nargs;
tree p = parms;
while (p && p != void_list_node)
{
count++;
p = TREE_CHAIN (p);
}
return unify_too_few_arguments (explain_p, ia, count);
}
if (!subr) if (!subr)
{ {
...@@ -14503,7 +14761,10 @@ type_unification_real (tree tparms, ...@@ -14503,7 +14761,10 @@ type_unification_real (tree tparms,
tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i)); tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
tree arg = TREE_PURPOSE (TREE_VEC_ELT (tparms, i)); tree arg = TREE_PURPOSE (TREE_VEC_ELT (tparms, i));
arg = tsubst_template_arg (arg, targs, tf_none, NULL_TREE); arg = tsubst_template_arg (arg, targs, tf_none, NULL_TREE);
arg = convert_template_argument (parm, arg, targs, tf_none, arg = convert_template_argument (parm, arg, targs,
(explain_p
? tf_warning_or_error
: tf_none),
i, NULL_TREE); i, NULL_TREE);
if (arg == error_mark_node) if (arg == error_mark_node)
return 1; return 1;
...@@ -14540,7 +14801,7 @@ type_unification_real (tree tparms, ...@@ -14540,7 +14801,7 @@ type_unification_real (tree tparms,
continue; continue;
} }
return 2; return unify_parameter_deduction_failure (explain_p, tparm);
} }
} }
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
...@@ -14548,7 +14809,7 @@ type_unification_real (tree tparms, ...@@ -14548,7 +14809,7 @@ type_unification_real (tree tparms,
SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, TREE_VEC_LENGTH (targs)); SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, TREE_VEC_LENGTH (targs));
#endif #endif
return 0; return unify_success (explain_p);
} }
/* Subroutine of type_unification_real. Args are like the variables /* Subroutine of type_unification_real. Args are like the variables
...@@ -14563,7 +14824,8 @@ resolve_overloaded_unification (tree tparms, ...@@ -14563,7 +14824,8 @@ resolve_overloaded_unification (tree tparms,
tree parm, tree parm,
tree arg, tree arg,
unification_kind_t strict, unification_kind_t strict,
int sub_strict) int sub_strict,
bool explain_p)
{ {
tree tempargs = copy_node (targs); tree tempargs = copy_node (targs);
int good = 0; int good = 0;
...@@ -14615,7 +14877,7 @@ resolve_overloaded_unification (tree tparms, ...@@ -14615,7 +14877,7 @@ resolve_overloaded_unification (tree tparms,
{ {
elem = tsubst (TREE_TYPE (fn), subargs, tf_none, NULL_TREE); elem = tsubst (TREE_TYPE (fn), subargs, tf_none, NULL_TREE);
if (try_one_overload (tparms, targs, tempargs, parm, if (try_one_overload (tparms, targs, tempargs, parm,
elem, strict, sub_strict, addr_p) elem, strict, sub_strict, addr_p, explain_p)
&& (!goodfn || !decls_match (goodfn, elem))) && (!goodfn || !decls_match (goodfn, elem)))
{ {
goodfn = elem; goodfn = elem;
...@@ -14643,7 +14905,7 @@ resolve_overloaded_unification (tree tparms, ...@@ -14643,7 +14905,7 @@ resolve_overloaded_unification (tree tparms,
for (; arg; arg = OVL_NEXT (arg)) for (; arg; arg = OVL_NEXT (arg))
if (try_one_overload (tparms, targs, tempargs, parm, if (try_one_overload (tparms, targs, tempargs, parm,
TREE_TYPE (OVL_CURRENT (arg)), TREE_TYPE (OVL_CURRENT (arg)),
strict, sub_strict, addr_p) strict, sub_strict, addr_p, explain_p)
&& (!goodfn || !decls_match (goodfn, OVL_CURRENT (arg)))) && (!goodfn || !decls_match (goodfn, OVL_CURRENT (arg))))
{ {
goodfn = OVL_CURRENT (arg); goodfn = OVL_CURRENT (arg);
...@@ -14790,7 +15052,8 @@ try_one_overload (tree tparms, ...@@ -14790,7 +15052,8 @@ try_one_overload (tree tparms,
tree arg, tree arg,
unification_kind_t strict, unification_kind_t strict,
int sub_strict, int sub_strict,
bool addr_p) bool addr_p,
bool explain_p)
{ {
int nargs; int nargs;
tree tempargs; tree tempargs;
...@@ -14820,7 +15083,7 @@ try_one_overload (tree tparms, ...@@ -14820,7 +15083,7 @@ try_one_overload (tree tparms,
nargs = TREE_VEC_LENGTH (targs); nargs = TREE_VEC_LENGTH (targs);
tempargs = make_tree_vec (nargs); tempargs = make_tree_vec (nargs);
if (unify (tparms, tempargs, parm, arg, sub_strict) != 0) if (unify (tparms, tempargs, parm, arg, sub_strict, explain_p))
return 0; return 0;
/* First make sure we didn't deduce anything that conflicts with /* First make sure we didn't deduce anything that conflicts with
...@@ -14858,7 +15121,8 @@ try_one_overload (tree tparms, ...@@ -14858,7 +15121,8 @@ try_one_overload (tree tparms,
TARGS are as for unify. */ TARGS are as for unify. */
static tree static tree
try_class_unification (tree tparms, tree targs, tree parm, tree arg) try_class_unification (tree tparms, tree targs, tree parm, tree arg,
bool explain_p)
{ {
tree copy_of_targs; tree copy_of_targs;
...@@ -14901,7 +15165,7 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg) ...@@ -14901,7 +15165,7 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg)
/* If unification failed, we're done. */ /* If unification failed, we're done. */
if (unify (tparms, copy_of_targs, CLASSTYPE_TI_ARGS (parm), if (unify (tparms, copy_of_targs, CLASSTYPE_TI_ARGS (parm),
CLASSTYPE_TI_ARGS (arg), UNIFY_ALLOW_NONE)) CLASSTYPE_TI_ARGS (arg), UNIFY_ALLOW_NONE, explain_p))
return NULL_TREE; return NULL_TREE;
return arg; return arg;
...@@ -14914,8 +15178,9 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg) ...@@ -14914,8 +15178,9 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg)
a partial specialization, as well as a plain template type. Used a partial specialization, as well as a plain template type. Used
by unify. */ by unify. */
static tree static enum template_base_result
get_template_base (tree tparms, tree targs, tree parm, tree arg) get_template_base (tree tparms, tree targs, tree parm, tree arg,
bool explain_p, tree *result)
{ {
tree rval = NULL_TREE; tree rval = NULL_TREE;
tree binfo; tree binfo;
...@@ -14924,14 +15189,18 @@ get_template_base (tree tparms, tree targs, tree parm, tree arg) ...@@ -14924,14 +15189,18 @@ get_template_base (tree tparms, tree targs, tree parm, tree arg)
binfo = TYPE_BINFO (complete_type (arg)); binfo = TYPE_BINFO (complete_type (arg));
if (!binfo) if (!binfo)
/* The type could not be completed. */ {
return NULL_TREE; /* The type could not be completed. */
*result = NULL_TREE;
return tbr_incomplete_type;
}
/* Walk in inheritance graph order. The search order is not /* Walk in inheritance graph order. The search order is not
important, and this avoids multiple walks of virtual bases. */ important, and this avoids multiple walks of virtual bases. */
for (binfo = TREE_CHAIN (binfo); binfo; binfo = TREE_CHAIN (binfo)) for (binfo = TREE_CHAIN (binfo); binfo; binfo = TREE_CHAIN (binfo))
{ {
tree r = try_class_unification (tparms, targs, parm, BINFO_TYPE (binfo)); tree r = try_class_unification (tparms, targs, parm,
BINFO_TYPE (binfo), explain_p);
if (r) if (r)
{ {
...@@ -14944,13 +15213,17 @@ get_template_base (tree tparms, tree targs, tree parm, tree arg) ...@@ -14944,13 +15213,17 @@ get_template_base (tree tparms, tree targs, tree parm, tree arg)
applies. */ applies. */
if (rval && !same_type_p (r, rval)) if (rval && !same_type_p (r, rval))
return NULL_TREE; {
*result = NULL_TREE;
return tbr_ambiguous_baseclass;
}
rval = r; rval = r;
} }
} }
return rval; *result = rval;
return tbr_success;
} }
/* Returns the level of DECL, which declares a template parameter. */ /* Returns the level of DECL, which declares a template parameter. */
...@@ -15032,6 +15305,12 @@ template_parm_level_and_index (tree parm, int* level, int* index) ...@@ -15032,6 +15305,12 @@ template_parm_level_and_index (tree parm, int* level, int* index)
} }
} }
#define RECUR_AND_CHECK_FAILURE(TP, TA, P, A, S, EP) \
do { \
if (unify (TP, TA, P, A, S, EP)) \
return 1; \
} while (0);
/* Unifies the remaining arguments in PACKED_ARGS with the pack /* Unifies the remaining arguments in PACKED_ARGS with the pack
expansion at the end of PACKED_PARMS. Returns 0 if the type expansion at the end of PACKED_PARMS. Returns 0 if the type
deduction succeeds, 1 otherwise. STRICT is the same as in deduction succeeds, 1 otherwise. STRICT is the same as in
...@@ -15039,10 +15318,10 @@ template_parm_level_and_index (tree parm, int* level, int* index) ...@@ -15039,10 +15318,10 @@ template_parm_level_and_index (tree parm, int* level, int* index)
call argument list. We'll need to adjust the arguments to make them call argument list. We'll need to adjust the arguments to make them
types. SUBR tells us if this is from a recursive call to types. SUBR tells us if this is from a recursive call to
type_unification_real. */ type_unification_real. */
int static int
unify_pack_expansion (tree tparms, tree targs, tree packed_parms, unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
tree packed_args, int strict, bool call_args_p, tree packed_args, int strict, bool call_args_p,
bool subr) bool subr, bool explain_p)
{ {
tree parm tree parm
= TREE_VEC_ELT (packed_parms, TREE_VEC_LENGTH (packed_parms) - 1); = TREE_VEC_ELT (packed_parms, TREE_VEC_LENGTH (packed_parms) - 1);
...@@ -15132,7 +15411,7 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms, ...@@ -15132,7 +15411,7 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
if (resolve_overloaded_unification if (resolve_overloaded_unification
(tparms, targs, parm, arg, (tparms, targs, parm, arg,
(unification_kind_t) strict, (unification_kind_t) strict,
sub_strict) sub_strict, explain_p)
!= 0) != 0)
return 1; return 1;
skip_arg_p = true; skip_arg_p = true;
...@@ -15160,8 +15439,8 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms, ...@@ -15160,8 +15439,8 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
/* For deduction from an init-list we need the actual list. */ /* For deduction from an init-list we need the actual list. */
if (arg_expr && BRACE_ENCLOSED_INITIALIZER_P (arg_expr)) if (arg_expr && BRACE_ENCLOSED_INITIALIZER_P (arg_expr))
arg = arg_expr; arg = arg_expr;
if (unify (tparms, targs, parm, arg, arg_strict)) RECUR_AND_CHECK_FAILURE (tparms, targs, parm, arg, arg_strict,
return 1; explain_p);
} }
} }
...@@ -15252,13 +15531,21 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms, ...@@ -15252,13 +15531,21 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
ARGUMENT_PACK_INCOMPLETE_P (old_pack) = 1; ARGUMENT_PACK_INCOMPLETE_P (old_pack) = 1;
ARGUMENT_PACK_EXPLICIT_ARGS (old_pack) = explicit_args; ARGUMENT_PACK_EXPLICIT_ARGS (old_pack) = explicit_args;
} }
else if (!comp_template_args (ARGUMENT_PACK_ARGS (old_pack), else
new_args)) {
/* Inconsistent unification of this parameter pack. */ tree bad_old_arg, bad_new_arg;
return 1; tree old_args = ARGUMENT_PACK_ARGS (old_pack);
if (!comp_template_args_with_info (old_args, new_args,
&bad_old_arg, &bad_new_arg))
/* Inconsistent unification of this parameter pack. */
return unify_parameter_pack_inconsistent (explain_p,
bad_old_arg,
bad_new_arg);
}
} }
return 0; return unify_success (explain_p);
} }
/* Deduce the value of template parameters. TPARMS is the (innermost) /* Deduce the value of template parameters. TPARMS is the (innermost)
...@@ -15303,7 +15590,8 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms, ...@@ -15303,7 +15590,8 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
qualified at this point. */ qualified at this point. */
static int static int
unify (tree tparms, tree targs, tree parm, tree arg, int strict) unify (tree tparms, tree targs, tree parm, tree arg, int strict,
bool explain_p)
{ {
int idx; int idx;
tree targ; tree targ;
...@@ -15318,19 +15606,19 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15318,19 +15606,19 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
parm = TREE_OPERAND (parm, 0); parm = TREE_OPERAND (parm, 0);
if (arg == error_mark_node) if (arg == error_mark_node)
return 1; return unify_invalid (explain_p);
if (arg == unknown_type_node if (arg == unknown_type_node
|| arg == init_list_type_node) || arg == init_list_type_node)
/* We can't deduce anything from this, but we might get all the /* We can't deduce anything from this, but we might get all the
template args from other function args. */ template args from other function args. */
return 0; return unify_success (explain_p);
/* If PARM uses template parameters, then we can't bail out here, /* If PARM uses template parameters, then we can't bail out here,
even if ARG == PARM, since we won't record unifications for the even if ARG == PARM, since we won't record unifications for the
template parameters. We might need them if we're trying to template parameters. We might need them if we're trying to
figure out which of two things is more specialized. */ figure out which of two things is more specialized. */
if (arg == parm && !uses_template_parms (parm)) if (arg == parm && !uses_template_parms (parm))
return 0; return unify_success (explain_p);
/* Handle init lists early, so the rest of the function can assume /* Handle init lists early, so the rest of the function can assume
we're dealing with a type. */ we're dealing with a type. */
...@@ -15349,7 +15637,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15349,7 +15637,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
/* We can only deduce from an initializer list argument if the /* We can only deduce from an initializer list argument if the
parameter is std::initializer_list; otherwise this is a parameter is std::initializer_list; otherwise this is a
non-deduced context. */ non-deduced context. */
return 0; return unify_success (explain_p);
elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (parm), 0); elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (parm), 0);
...@@ -15358,7 +15646,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15358,7 +15646,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
int elt_strict = strict; int elt_strict = strict;
if (elt == error_mark_node) if (elt == error_mark_node)
return 1; return unify_invalid (explain_p);
if (!BRACE_ENCLOSED_INITIALIZER_P (elt)) if (!BRACE_ENCLOSED_INITIALIZER_P (elt))
{ {
...@@ -15370,8 +15658,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15370,8 +15658,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
elt = type; elt = type;
} }
if (unify (tparms, targs, elttype, elt, elt_strict)) RECUR_AND_CHECK_FAILURE (tparms, targs, elttype, elt, elt_strict,
return 1; explain_p);
} }
/* If the std::initializer_list<T> deduction worked, replace the /* If the std::initializer_list<T> deduction worked, replace the
...@@ -15383,7 +15671,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15383,7 +15671,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
targ = listify (targ); targ = listify (targ);
TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = targ; TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = targ;
} }
return 0; return unify_success (explain_p);
} }
/* Immediately reject some pairs that won't unify because of /* Immediately reject some pairs that won't unify because of
...@@ -15400,7 +15688,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15400,7 +15688,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
is more specialized, for example. */ is more specialized, for example. */
&& TREE_CODE (arg) != TEMPLATE_TYPE_PARM && TREE_CODE (arg) != TEMPLATE_TYPE_PARM
&& !check_cv_quals_for_unify (strict_in, arg, parm)) && !check_cv_quals_for_unify (strict_in, arg, parm))
return 1; return unify_cv_qual_mismatch (explain_p, parm, arg);
if (!(strict & UNIFY_ALLOW_OUTER_LEVEL) if (!(strict & UNIFY_ALLOW_OUTER_LEVEL)
&& TYPE_P (parm) && !CP_TYPE_CONST_P (parm)) && TYPE_P (parm) && !CP_TYPE_CONST_P (parm))
...@@ -15418,21 +15706,26 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15418,21 +15706,26 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
/* In a type which contains a nested-name-specifier, template /* In a type which contains a nested-name-specifier, template
argument values cannot be deduced for template parameters used argument values cannot be deduced for template parameters used
within the nested-name-specifier. */ within the nested-name-specifier. */
return 0; return unify_success (explain_p);
case TEMPLATE_TYPE_PARM: case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM: case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM: case BOUND_TEMPLATE_TEMPLATE_PARM:
tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0)); tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0));
if (tparm == error_mark_node) if (tparm == error_mark_node)
return 1; return unify_invalid (explain_p);
if (TEMPLATE_TYPE_LEVEL (parm) if (TEMPLATE_TYPE_LEVEL (parm)
!= template_decl_level (tparm)) != template_decl_level (tparm))
/* The PARM is not one we're trying to unify. Just check /* The PARM is not one we're trying to unify. Just check
to see if it matches ARG. */ to see if it matches ARG. */
return (TREE_CODE (arg) == TREE_CODE (parm) {
&& same_type_p (parm, arg)) ? 0 : 1; if (TREE_CODE (arg) == TREE_CODE (parm)
&& same_type_p (parm, arg))
return unify_success (explain_p);
else
return unify_type_mismatch (explain_p, parm, arg);
}
idx = TEMPLATE_TYPE_IDX (parm); idx = TEMPLATE_TYPE_IDX (parm);
targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx); targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx);
tparm = TREE_VALUE (TREE_VEC_ELT (tparms, idx)); tparm = TREE_VALUE (TREE_VEC_ELT (tparms, idx));
...@@ -15442,7 +15735,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15442,7 +15735,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
&& TREE_CODE (tparm) != TYPE_DECL) && TREE_CODE (tparm) != TYPE_DECL)
|| (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM || (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
&& TREE_CODE (tparm) != TEMPLATE_DECL)) && TREE_CODE (tparm) != TEMPLATE_DECL))
return 1; gcc_unreachable ();
if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM) if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
{ {
...@@ -15450,7 +15743,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15450,7 +15743,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
template parameter. */ template parameter. */
if (TREE_CODE (arg) != BOUND_TEMPLATE_TEMPLATE_PARM if (TREE_CODE (arg) != BOUND_TEMPLATE_TEMPLATE_PARM
&& !CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P (arg)) && !CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P (arg))
return 1; return unify_template_deduction_failure (explain_p, parm, arg);
{ {
tree parmvec = TYPE_TI_ARGS (parm); tree parmvec = TYPE_TI_ARGS (parm);
...@@ -15492,7 +15785,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15492,7 +15785,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
if (coerce_template_parms (parm_parms, if (coerce_template_parms (parm_parms,
full_argvec, full_argvec,
TYPE_TI_TEMPLATE (parm), TYPE_TI_TEMPLATE (parm),
tf_none, (explain_p
? tf_warning_or_error
: tf_none),
/*require_all_args=*/true, /*require_all_args=*/true,
/*use_default_args=*/false) /*use_default_args=*/false)
== error_mark_node) == error_mark_node)
...@@ -15515,15 +15810,15 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15515,15 +15810,15 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
parm_variadic_p = 1; parm_variadic_p = 1;
if (TREE_VEC_LENGTH (argvec) < len - parm_variadic_p) if (TREE_VEC_LENGTH (argvec) < len - parm_variadic_p)
return 1; return unify_too_few_arguments (explain_p,
TREE_VEC_LENGTH (argvec), len);
for (i = 0; i < len - parm_variadic_p; ++i) for (i = 0; i < len - parm_variadic_p; ++i)
{ {
if (unify (tparms, targs, RECUR_AND_CHECK_FAILURE (tparms, targs,
TREE_VEC_ELT (parmvec, i), TREE_VEC_ELT (parmvec, i),
TREE_VEC_ELT (argvec, i), TREE_VEC_ELT (argvec, i),
UNIFY_ALLOW_NONE)) UNIFY_ALLOW_NONE, explain_p);
return 1;
} }
if (parm_variadic_p if (parm_variadic_p
...@@ -15531,7 +15826,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15531,7 +15826,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
parmvec, argvec, parmvec, argvec,
UNIFY_ALLOW_NONE, UNIFY_ALLOW_NONE,
/*call_args_p=*/false, /*call_args_p=*/false,
/*subr=*/false)) /*subr=*/false, explain_p))
return 1; return 1;
} }
arg = TYPE_TI_TEMPLATE (arg); arg = TYPE_TI_TEMPLATE (arg);
...@@ -15546,9 +15841,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15546,9 +15841,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
/* Simple cases: Value already set, does match or doesn't. */ /* Simple cases: Value already set, does match or doesn't. */
if (targ != NULL_TREE && template_args_equal (targ, arg)) if (targ != NULL_TREE && template_args_equal (targ, arg))
return 0; return unify_success (explain_p);
else if (targ) else if (targ)
return 1; return unify_inconsistency (explain_p, parm, targ, arg);
} }
else else
{ {
...@@ -15558,20 +15853,20 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15558,20 +15853,20 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
that binds `const int' to `T'. */ that binds `const int' to `T'. */
if (!check_cv_quals_for_unify (strict_in | UNIFY_ALLOW_LESS_CV_QUAL, if (!check_cv_quals_for_unify (strict_in | UNIFY_ALLOW_LESS_CV_QUAL,
arg, parm)) arg, parm))
return 1; return unify_cv_qual_mismatch (explain_p, parm, arg);
/* Consider the case where ARG is `const volatile int' and /* Consider the case where ARG is `const volatile int' and
PARM is `const T'. Then, T should be `volatile int'. */ PARM is `const T'. Then, T should be `volatile int'. */
arg = cp_build_qualified_type_real arg = cp_build_qualified_type_real
(arg, cp_type_quals (arg) & ~cp_type_quals (parm), tf_none); (arg, cp_type_quals (arg) & ~cp_type_quals (parm), tf_none);
if (arg == error_mark_node) if (arg == error_mark_node)
return 1; return unify_invalid (explain_p);
/* Simple cases: Value already set, does match or doesn't. */ /* Simple cases: Value already set, does match or doesn't. */
if (targ != NULL_TREE && same_type_p (targ, arg)) if (targ != NULL_TREE && same_type_p (targ, arg))
return 0; return unify_success (explain_p);
else if (targ) else if (targ)
return 1; return unify_inconsistency (explain_p, parm, targ, arg);
/* Make sure that ARG is not a variable-sized array. (Note /* Make sure that ARG is not a variable-sized array. (Note
that were talking about variable-sized arrays (like that were talking about variable-sized arrays (like
...@@ -15581,7 +15876,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15581,7 +15876,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
instantiation. Besides, such types are not allowed in instantiation. Besides, such types are not allowed in
ISO C++, so we can do as we please here. */ ISO C++, so we can do as we please here. */
if (variably_modified_type_p (arg, NULL_TREE)) if (variably_modified_type_p (arg, NULL_TREE))
return 1; return unify_vla_arg (explain_p, arg);
/* Strip typedefs as in convert_template_argument. */ /* Strip typedefs as in convert_template_argument. */
arg = canonicalize_type_argument (arg, tf_none); arg = canonicalize_type_argument (arg, tf_none);
...@@ -15591,35 +15886,45 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15591,35 +15886,45 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
against it unless PARM is also a parameter pack. */ against it unless PARM is also a parameter pack. */
if ((template_parameter_pack_p (arg) || PACK_EXPANSION_P (arg)) if ((template_parameter_pack_p (arg) || PACK_EXPANSION_P (arg))
&& !template_parameter_pack_p (parm)) && !template_parameter_pack_p (parm))
return 1; return unify_parameter_pack_mismatch (explain_p, parm, arg);
/* If the argument deduction results is a METHOD_TYPE, /* If the argument deduction results is a METHOD_TYPE,
then there is a problem. then there is a problem.
METHOD_TYPE doesn't map to any real C++ type the result of METHOD_TYPE doesn't map to any real C++ type the result of
the deduction can not be of that type. */ the deduction can not be of that type. */
if (TREE_CODE (arg) == METHOD_TYPE) if (TREE_CODE (arg) == METHOD_TYPE)
return 1; return unify_method_type_error (explain_p, arg);
TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg; TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
return 0; return unify_success (explain_p);
case TEMPLATE_PARM_INDEX: case TEMPLATE_PARM_INDEX:
tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0)); tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0));
if (tparm == error_mark_node) if (tparm == error_mark_node)
return 1; return unify_invalid (explain_p);
if (TEMPLATE_PARM_LEVEL (parm) if (TEMPLATE_PARM_LEVEL (parm)
!= template_decl_level (tparm)) != template_decl_level (tparm))
/* The PARM is not one we're trying to unify. Just check {
to see if it matches ARG. */ /* The PARM is not one we're trying to unify. Just check
return !(TREE_CODE (arg) == TREE_CODE (parm) to see if it matches ARG. */
&& cp_tree_equal (parm, arg)); int result = !(TREE_CODE (arg) == TREE_CODE (parm)
&& cp_tree_equal (parm, arg));
if (result)
unify_expression_unequal (explain_p, parm, arg);
return result;
}
idx = TEMPLATE_PARM_IDX (parm); idx = TEMPLATE_PARM_IDX (parm);
targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx); targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx);
if (targ) if (targ)
return !cp_tree_equal (targ, arg); {
int x = !cp_tree_equal (targ, arg);
if (x)
unify_inconsistency (explain_p, parm, targ, arg);
return x;
}
/* [temp.deduct.type] If, in the declaration of a function template /* [temp.deduct.type] If, in the declaration of a function template
with a non-type template-parameter, the non-type with a non-type template-parameter, the non-type
...@@ -15646,25 +15951,25 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15646,25 +15951,25 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
else if (uses_template_parms (tparm)) else if (uses_template_parms (tparm))
/* We haven't deduced the type of this parameter yet. Try again /* We haven't deduced the type of this parameter yet. Try again
later. */ later. */
return 0; return unify_success (explain_p);
else else
return 1; return unify_type_mismatch (explain_p, tparm, arg);
/* If ARG is a parameter pack or an expansion, we cannot unify /* If ARG is a parameter pack or an expansion, we cannot unify
against it unless PARM is also a parameter pack. */ against it unless PARM is also a parameter pack. */
if ((template_parameter_pack_p (arg) || PACK_EXPANSION_P (arg)) if ((template_parameter_pack_p (arg) || PACK_EXPANSION_P (arg))
&& !TEMPLATE_PARM_PARAMETER_PACK (parm)) && !TEMPLATE_PARM_PARAMETER_PACK (parm))
return 1; return unify_parameter_pack_mismatch (explain_p, parm, arg);
TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg; TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
return 0; return unify_success (explain_p);
case PTRMEM_CST: case PTRMEM_CST:
{ {
/* A pointer-to-member constant can be unified only with /* A pointer-to-member constant can be unified only with
another constant. */ another constant. */
if (TREE_CODE (arg) != PTRMEM_CST) if (TREE_CODE (arg) != PTRMEM_CST)
return 1; return unify_ptrmem_cst_mismatch (explain_p, parm, arg);
/* Just unify the class member. It would be useless (and possibly /* Just unify the class member. It would be useless (and possibly
wrong, depending on the strict flags) to unify also wrong, depending on the strict flags) to unify also
...@@ -15677,13 +15982,13 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15677,13 +15982,13 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
Unification of &A::x and &B::x must succeed. */ Unification of &A::x and &B::x must succeed. */
return unify (tparms, targs, PTRMEM_CST_MEMBER (parm), return unify (tparms, targs, PTRMEM_CST_MEMBER (parm),
PTRMEM_CST_MEMBER (arg), strict); PTRMEM_CST_MEMBER (arg), strict, explain_p);
} }
case POINTER_TYPE: case POINTER_TYPE:
{ {
if (TREE_CODE (arg) != POINTER_TYPE) if (TREE_CODE (arg) != POINTER_TYPE)
return 1; return unify_type_mismatch (explain_p, parm, arg);
/* [temp.deduct.call] /* [temp.deduct.call]
...@@ -15701,21 +16006,21 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15701,21 +16006,21 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
strict |= (strict_in & UNIFY_ALLOW_DERIVED); strict |= (strict_in & UNIFY_ALLOW_DERIVED);
return unify (tparms, targs, TREE_TYPE (parm), return unify (tparms, targs, TREE_TYPE (parm),
TREE_TYPE (arg), strict); TREE_TYPE (arg), strict, explain_p);
} }
case REFERENCE_TYPE: case REFERENCE_TYPE:
if (TREE_CODE (arg) != REFERENCE_TYPE) if (TREE_CODE (arg) != REFERENCE_TYPE)
return 1; return unify_type_mismatch (explain_p, parm, arg);
return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg), return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
strict & UNIFY_ALLOW_MORE_CV_QUAL); strict & UNIFY_ALLOW_MORE_CV_QUAL, explain_p);
case ARRAY_TYPE: case ARRAY_TYPE:
if (TREE_CODE (arg) != ARRAY_TYPE) if (TREE_CODE (arg) != ARRAY_TYPE)
return 1; return unify_type_mismatch (explain_p, parm, arg);
if ((TYPE_DOMAIN (parm) == NULL_TREE) if ((TYPE_DOMAIN (parm) == NULL_TREE)
!= (TYPE_DOMAIN (arg) == NULL_TREE)) != (TYPE_DOMAIN (arg) == NULL_TREE))
return 1; return unify_type_mismatch (explain_p, parm, arg);
if (TYPE_DOMAIN (parm) != NULL_TREE) if (TYPE_DOMAIN (parm) != NULL_TREE)
{ {
tree parm_max; tree parm_max;
...@@ -15754,7 +16059,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15754,7 +16059,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
Here, the type of the ARG will be "int [g(i)]", and Here, the type of the ARG will be "int [g(i)]", and
may be a SAVE_EXPR, etc. */ may be a SAVE_EXPR, etc. */
if (TREE_CODE (arg_max) != MINUS_EXPR) if (TREE_CODE (arg_max) != MINUS_EXPR)
return 1; return unify_vla_arg (explain_p, arg);
arg_max = TREE_OPERAND (arg_max, 0); arg_max = TREE_OPERAND (arg_max, 0);
} }
...@@ -15771,11 +16076,11 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15771,11 +16076,11 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
arg_max, arg_max,
integer_one_node); integer_one_node);
if (unify (tparms, targs, parm_max, arg_max, UNIFY_ALLOW_INTEGER)) RECUR_AND_CHECK_FAILURE (tparms, targs, parm_max, arg_max,
return 1; UNIFY_ALLOW_INTEGER, explain_p);
} }
return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg), return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
strict & UNIFY_ALLOW_MORE_CV_QUAL); strict & UNIFY_ALLOW_MORE_CV_QUAL, explain_p);
case REAL_TYPE: case REAL_TYPE:
case COMPLEX_TYPE: case COMPLEX_TYPE:
...@@ -15785,16 +16090,16 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15785,16 +16090,16 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
case ENUMERAL_TYPE: case ENUMERAL_TYPE:
case VOID_TYPE: case VOID_TYPE:
if (TREE_CODE (arg) != TREE_CODE (parm)) if (TREE_CODE (arg) != TREE_CODE (parm))
return 1; return unify_type_mismatch (explain_p, parm, arg);
/* We have already checked cv-qualification at the top of the /* We have already checked cv-qualification at the top of the
function. */ function. */
if (!same_type_ignoring_top_level_qualifiers_p (arg, parm)) if (!same_type_ignoring_top_level_qualifiers_p (arg, parm))
return 1; return unify_type_mismatch (explain_p, parm, arg);
/* As far as unification is concerned, this wins. Later checks /* As far as unification is concerned, this wins. Later checks
will invalidate it if necessary. */ will invalidate it if necessary. */
return 0; return unify_success (explain_p);
/* Types INTEGER_CST and MINUS_EXPR can come from array bounds. */ /* Types INTEGER_CST and MINUS_EXPR can come from array bounds. */
/* Type INTEGER_CST can come from ordinary constant template args. */ /* Type INTEGER_CST can come from ordinary constant template args. */
...@@ -15803,38 +16108,41 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15803,38 +16108,41 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
arg = TREE_OPERAND (arg, 0); arg = TREE_OPERAND (arg, 0);
if (TREE_CODE (arg) != INTEGER_CST) if (TREE_CODE (arg) != INTEGER_CST)
return 1; return unify_template_argument_mismatch (explain_p, parm, arg);
return !tree_int_cst_equal (parm, arg); return (tree_int_cst_equal (parm, arg)
? unify_success (explain_p)
: unify_template_argument_mismatch (explain_p, parm, arg));
case TREE_VEC: case TREE_VEC:
{ {
int i; int i;
if (TREE_CODE (arg) != TREE_VEC) if (TREE_CODE (arg) != TREE_VEC)
return 1; return unify_template_argument_mismatch (explain_p, parm, arg);
if (TREE_VEC_LENGTH (parm) != TREE_VEC_LENGTH (arg)) if (TREE_VEC_LENGTH (parm) != TREE_VEC_LENGTH (arg))
return 1; return unify_arity (explain_p, TREE_VEC_LENGTH (arg),
TREE_VEC_LENGTH (parm));
for (i = 0; i < TREE_VEC_LENGTH (parm); ++i) for (i = 0; i < TREE_VEC_LENGTH (parm); ++i)
if (unify (tparms, targs, RECUR_AND_CHECK_FAILURE (tparms, targs,
TREE_VEC_ELT (parm, i), TREE_VEC_ELT (arg, i), TREE_VEC_ELT (parm, i),
UNIFY_ALLOW_NONE)) TREE_VEC_ELT (arg, i),
return 1; UNIFY_ALLOW_NONE, explain_p);
return 0; return unify_success (explain_p);
} }
case RECORD_TYPE: case RECORD_TYPE:
case UNION_TYPE: case UNION_TYPE:
if (TREE_CODE (arg) != TREE_CODE (parm)) if (TREE_CODE (arg) != TREE_CODE (parm))
return 1; return unify_type_mismatch (explain_p, parm, arg);
if (TYPE_PTRMEMFUNC_P (parm)) if (TYPE_PTRMEMFUNC_P (parm))
{ {
if (!TYPE_PTRMEMFUNC_P (arg)) if (!TYPE_PTRMEMFUNC_P (arg))
return 1; return unify_type_mismatch (explain_p, parm, arg);
return unify (tparms, targs, return unify (tparms, targs,
TYPE_PTRMEMFUNC_FN_TYPE (parm), TYPE_PTRMEMFUNC_FN_TYPE (parm),
TYPE_PTRMEMFUNC_FN_TYPE (arg), TYPE_PTRMEMFUNC_FN_TYPE (arg),
strict); strict, explain_p);
} }
if (CLASSTYPE_TEMPLATE_INFO (parm)) if (CLASSTYPE_TEMPLATE_INFO (parm))
...@@ -15845,7 +16153,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15845,7 +16153,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
{ {
/* First, we try to unify the PARM and ARG directly. */ /* First, we try to unify the PARM and ARG directly. */
t = try_class_unification (tparms, targs, t = try_class_unification (tparms, targs,
parm, arg); parm, arg, explain_p);
if (!t) if (!t)
{ {
...@@ -15858,10 +16166,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15858,10 +16166,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
a class of the form template-id, A can be a a class of the form template-id, A can be a
pointer to a derived class pointed to by the pointer to a derived class pointed to by the
deduced A. */ deduced A. */
t = get_template_base (tparms, targs, parm, arg); enum template_base_result r;
r = get_template_base (tparms, targs, parm, arg,
explain_p, &t);
if (!t) if (!t)
return 1; return unify_no_common_base (explain_p, r, parm, arg);
} }
} }
else if (CLASSTYPE_TEMPLATE_INFO (arg) else if (CLASSTYPE_TEMPLATE_INFO (arg)
...@@ -15872,14 +16182,14 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15872,14 +16182,14 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
t = arg; t = arg;
else else
/* There's no chance of unification succeeding. */ /* There's no chance of unification succeeding. */
return 1; return unify_type_mismatch (explain_p, parm, arg);
return unify (tparms, targs, CLASSTYPE_TI_ARGS (parm), return unify (tparms, targs, CLASSTYPE_TI_ARGS (parm),
CLASSTYPE_TI_ARGS (t), UNIFY_ALLOW_NONE); CLASSTYPE_TI_ARGS (t), UNIFY_ALLOW_NONE, explain_p);
} }
else if (!same_type_ignoring_top_level_qualifiers_p (parm, arg)) else if (!same_type_ignoring_top_level_qualifiers_p (parm, arg))
return 1; return unify_type_mismatch (explain_p, parm, arg);
return 0; return unify_success (explain_p);
case METHOD_TYPE: case METHOD_TYPE:
case FUNCTION_TYPE: case FUNCTION_TYPE:
...@@ -15890,7 +16200,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15890,7 +16200,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
unsigned int i; unsigned int i;
if (TREE_CODE (arg) != TREE_CODE (parm)) if (TREE_CODE (arg) != TREE_CODE (parm))
return 1; return unify_type_mismatch (explain_p, parm, arg);
/* CV qualifications for methods can never be deduced, they must /* CV qualifications for methods can never be deduced, they must
match exactly. We need to check them explicitly here, match exactly. We need to check them explicitly here,
...@@ -15901,11 +16211,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15901,11 +16211,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
(UNIFY_ALLOW_NONE, (UNIFY_ALLOW_NONE,
class_of_this_parm (arg), class_of_this_parm (arg),
class_of_this_parm (parm)))) class_of_this_parm (parm))))
return 1; return unify_cv_qual_mismatch (explain_p, parm, arg);
if (unify (tparms, targs, TREE_TYPE (parm), RECUR_AND_CHECK_FAILURE (tparms, targs, TREE_TYPE (parm),
TREE_TYPE (arg), UNIFY_ALLOW_NONE)) TREE_TYPE (arg), UNIFY_ALLOW_NONE, explain_p);
return 1;
nargs = list_length (TYPE_ARG_TYPES (arg)); nargs = list_length (TYPE_ARG_TYPES (arg));
args = XALLOCAVEC (tree, nargs); args = XALLOCAVEC (tree, nargs);
...@@ -15917,7 +16226,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15917,7 +16226,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm), return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
args, nargs, 1, DEDUCE_EXACT, args, nargs, 1, DEDUCE_EXACT,
LOOKUP_NORMAL); LOOKUP_NORMAL, explain_p);
} }
case OFFSET_TYPE: case OFFSET_TYPE:
...@@ -15930,11 +16239,11 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15930,11 +16239,11 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
/* Check top-level cv qualifiers */ /* Check top-level cv qualifiers */
if (!check_cv_quals_for_unify (UNIFY_ALLOW_NONE, arg, parm)) if (!check_cv_quals_for_unify (UNIFY_ALLOW_NONE, arg, parm))
return 1; return unify_cv_qual_mismatch (explain_p, parm, arg);
if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm), RECUR_AND_CHECK_FAILURE (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
TYPE_PTRMEMFUNC_OBJECT_TYPE (arg), UNIFY_ALLOW_NONE)) TYPE_PTRMEMFUNC_OBJECT_TYPE (arg),
return 1; UNIFY_ALLOW_NONE, explain_p);
/* Determine the type of the function we are unifying against. */ /* Determine the type of the function we are unifying against. */
method_type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (arg)); method_type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (arg));
...@@ -15946,28 +16255,28 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15946,28 +16255,28 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
implicit object parameter and place them on the function implicit object parameter and place them on the function
type to be restored later. */ type to be restored later. */
fntype = apply_memfn_quals (fntype, type_memfn_quals (method_type)); fntype = apply_memfn_quals (fntype, type_memfn_quals (method_type));
return unify (tparms, targs, TREE_TYPE (parm), fntype, strict); return unify (tparms, targs, TREE_TYPE (parm), fntype, strict, explain_p);
} }
if (TREE_CODE (arg) != OFFSET_TYPE) if (TREE_CODE (arg) != OFFSET_TYPE)
return 1; return unify_type_mismatch (explain_p, parm, arg);
if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm), RECUR_AND_CHECK_FAILURE (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
TYPE_OFFSET_BASETYPE (arg), UNIFY_ALLOW_NONE)) TYPE_OFFSET_BASETYPE (arg),
return 1; UNIFY_ALLOW_NONE, explain_p);
return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg), return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
strict); strict, explain_p);
case CONST_DECL: case CONST_DECL:
if (DECL_TEMPLATE_PARM_P (parm)) if (DECL_TEMPLATE_PARM_P (parm))
return unify (tparms, targs, DECL_INITIAL (parm), arg, strict); return unify (tparms, targs, DECL_INITIAL (parm), arg, strict, explain_p);
if (arg != integral_constant_value (parm)) if (arg != integral_constant_value (parm))
return 1; return unify_template_argument_mismatch (explain_p, parm, arg);
return 0; return unify_success (explain_p);
case FIELD_DECL: case FIELD_DECL:
case TEMPLATE_DECL: case TEMPLATE_DECL:
/* Matched cases are handled by the ARG == PARM test above. */ /* Matched cases are handled by the ARG == PARM test above. */
return 1; return unify_template_argument_mismatch (explain_p, parm, arg);
case VAR_DECL: case VAR_DECL:
/* A non-type template parameter that is a variable should be a /* A non-type template parameter that is a variable should be a
...@@ -15997,7 +16306,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -15997,7 +16306,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
/* Since there is something following the pack /* Since there is something following the pack
expansion, we cannot unify this template argument expansion, we cannot unify this template argument
list. */ list. */
return 0; return unify_success (explain_p);
} }
} }
...@@ -16006,25 +16315,27 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -16006,25 +16315,27 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
(not counting the pack expression at the end), or we have (not counting the pack expression at the end), or we have
too many arguments for a parameter list that doesn't end in too many arguments for a parameter list that doesn't end in
a pack expression, we can't unify. */ a pack expression, we can't unify. */
if (argslen < (len - parm_variadic_p) if (argslen < (len - parm_variadic_p))
|| (argslen > len && !parm_variadic_p)) return unify_too_few_arguments (explain_p, argslen, len);
return 1; if (argslen > len && !parm_variadic_p)
return unify_too_many_arguments (explain_p, argslen, len);
/* Unify all of the parameters that precede the (optional) /* Unify all of the parameters that precede the (optional)
pack expression. */ pack expression. */
for (i = 0; i < len - parm_variadic_p; ++i) for (i = 0; i < len - parm_variadic_p; ++i)
{ {
if (unify (tparms, targs, TREE_VEC_ELT (packed_parms, i), RECUR_AND_CHECK_FAILURE (tparms, targs,
TREE_VEC_ELT (packed_args, i), strict)) TREE_VEC_ELT (packed_parms, i),
return 1; TREE_VEC_ELT (packed_args, i),
strict, explain_p);
} }
if (parm_variadic_p) if (parm_variadic_p)
return unify_pack_expansion (tparms, targs, return unify_pack_expansion (tparms, targs,
packed_parms, packed_args, packed_parms, packed_args,
strict, /*call_args_p=*/false, strict, /*call_args_p=*/false,
/*subr=*/false); /*subr=*/false, explain_p);
return 0; return unify_success (explain_p);
} }
break; break;
...@@ -16034,16 +16345,16 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -16034,16 +16345,16 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
case UNDERLYING_TYPE: case UNDERLYING_TYPE:
/* Cannot deduce anything from TYPEOF_TYPE, DECLTYPE_TYPE, /* Cannot deduce anything from TYPEOF_TYPE, DECLTYPE_TYPE,
or UNDERLYING_TYPE nodes. */ or UNDERLYING_TYPE nodes. */
return 0; return unify_success (explain_p);
case ERROR_MARK: case ERROR_MARK:
/* Unification fails if we hit an error node. */ /* Unification fails if we hit an error node. */
return 1; return unify_invalid (explain_p);
default: default:
/* An unresolved overload is a nondeduced context. */ /* An unresolved overload is a nondeduced context. */
if (type_unknown_p (parm)) if (type_unknown_p (parm))
return 0; return unify_success (explain_p);
gcc_assert (EXPR_P (parm)); gcc_assert (EXPR_P (parm));
/* We must be looking at an expression. This can happen with /* We must be looking at an expression. This can happen with
...@@ -16067,11 +16378,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -16067,11 +16378,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
if (!uses_template_parms (parm) if (!uses_template_parms (parm)
&& !template_args_equal (parm, arg)) && !template_args_equal (parm, arg))
return 1; return unify_expression_unequal (explain_p, parm, arg);
else else
return 0; return unify_success (explain_p);
} }
} }
#undef RECUR_AND_CHECK_FAILURE
/* Note that DECL can be defined in this translation unit, if /* Note that DECL can be defined in this translation unit, if
required. */ required. */
...@@ -16334,10 +16646,11 @@ more_specialized_fn (tree pat1, tree pat2, int len) ...@@ -16334,10 +16646,11 @@ more_specialized_fn (tree pat1, tree pat2, int len)
for (i = 0; i < len2; i++, ta = TREE_CHAIN (ta)) for (i = 0; i < len2; i++, ta = TREE_CHAIN (ta))
TREE_VEC_ELT (argvec, i) = TREE_VALUE (ta); TREE_VEC_ELT (argvec, i) = TREE_VALUE (ta);
deduce1 = !unify_pack_expansion (tparms1, targs1, parmvec, deduce1 = (unify_pack_expansion (tparms1, targs1, parmvec,
argvec, UNIFY_ALLOW_NONE, argvec, UNIFY_ALLOW_NONE,
/*call_args_p=*/false, /*call_args_p=*/false,
/*subr=*/0); /*subr=*/0, /*explain_p=*/false)
== 0);
/* We cannot deduce in the other direction, because ARG1 is /* We cannot deduce in the other direction, because ARG1 is
a pack expansion but ARG2 is not. */ a pack expansion but ARG2 is not. */
...@@ -16358,10 +16671,11 @@ more_specialized_fn (tree pat1, tree pat2, int len) ...@@ -16358,10 +16671,11 @@ more_specialized_fn (tree pat1, tree pat2, int len)
for (i = 0; i < len1; i++, ta = TREE_CHAIN (ta)) for (i = 0; i < len1; i++, ta = TREE_CHAIN (ta))
TREE_VEC_ELT (argvec, i) = TREE_VALUE (ta); TREE_VEC_ELT (argvec, i) = TREE_VALUE (ta);
deduce2 = !unify_pack_expansion (tparms2, targs2, parmvec, deduce2 = (unify_pack_expansion (tparms2, targs2, parmvec,
argvec, UNIFY_ALLOW_NONE, argvec, UNIFY_ALLOW_NONE,
/*call_args_p=*/false, /*call_args_p=*/false,
/*subr=*/0); /*subr=*/0, /*explain_p=*/false)
== 0);
/* We cannot deduce in the other direction, because ARG2 is /* We cannot deduce in the other direction, because ARG2 is
a pack expansion but ARG1 is not.*/ a pack expansion but ARG1 is not.*/
...@@ -16372,8 +16686,12 @@ more_specialized_fn (tree pat1, tree pat2, int len) ...@@ -16372,8 +16686,12 @@ more_specialized_fn (tree pat1, tree pat2, int len)
{ {
/* The normal case, where neither argument is a pack /* The normal case, where neither argument is a pack
expansion. */ expansion. */
deduce1 = !unify (tparms1, targs1, arg1, arg2, UNIFY_ALLOW_NONE); deduce1 = (unify (tparms1, targs1, arg1, arg2,
deduce2 = !unify (tparms2, targs2, arg2, arg1, UNIFY_ALLOW_NONE); UNIFY_ALLOW_NONE, /*explain_p=*/false)
== 0);
deduce2 = (unify (tparms2, targs2, arg2, arg1,
UNIFY_ALLOW_NONE, /*explain_p=*/false)
== 0);
} }
/* If we couldn't deduce arguments for tparms1 to make arg1 match /* If we couldn't deduce arguments for tparms1 to make arg1 match
...@@ -16587,7 +16905,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype) ...@@ -16587,7 +16905,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
args, ix, args, ix,
(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, LOOKUP_NORMAL)) DEDUCE_EXACT, LOOKUP_NORMAL, /*explain_p=*/false))
return NULL_TREE; return NULL_TREE;
return targs; return targs;
...@@ -16629,7 +16947,7 @@ get_class_bindings (tree tparms, tree spec_args, tree args) ...@@ -16629,7 +16947,7 @@ get_class_bindings (tree tparms, tree spec_args, tree args)
if (unify (tparms, deduced_args, if (unify (tparms, deduced_args,
INNERMOST_TEMPLATE_ARGS (spec_args), INNERMOST_TEMPLATE_ARGS (spec_args),
INNERMOST_TEMPLATE_ARGS (args), INNERMOST_TEMPLATE_ARGS (args),
UNIFY_ALLOW_NONE)) UNIFY_ALLOW_NONE, /*explain_p=*/false))
return NULL_TREE; return NULL_TREE;
for (i = 0; i < ntparms; ++i) for (i = 0; i < ntparms; ++i)
...@@ -19436,7 +19754,8 @@ do_auto_deduction (tree type, tree init, tree auto_node) ...@@ -19436,7 +19754,8 @@ do_auto_deduction (tree type, tree init, tree auto_node)
TREE_VEC_ELT (tparms, 0) TREE_VEC_ELT (tparms, 0)
= build_tree_list (NULL_TREE, TYPE_NAME (auto_node)); = build_tree_list (NULL_TREE, TYPE_NAME (auto_node));
val = type_unification_real (tparms, targs, parms, args, 1, 0, val = type_unification_real (tparms, targs, parms, args, 1, 0,
DEDUCE_CALL, LOOKUP_NORMAL); DEDUCE_CALL, LOOKUP_NORMAL,
/*explain_p=*/false);
if (val > 0) if (val > 0)
{ {
if (processing_template_decl) if (processing_template_decl)
......
2011-07-16 Nathan Froyd <froydnj@codesourcery.com>
Jason Merrill <jason@redhat.com>
PR c++/45329
PR c++/48934
* g++.dg/cpp0x/decltype29.C: Adjust.
* g++.dg/cpp0x/error4.C: Adjust.
* g++.dg/cpp0x/sfinae26.C: Adjust.
* g++.dg/cpp0x/variadic105.C: Adjust.
* g++.dg/template/deduce3.C: Adjust.
* g++.dg/template/error45.C: Adjust.
* g++.dg/template/ptrmem2.C: Adjust.
* g++.dg/template/sfinae2.C: Adjust.
* g++.old-deja/g++.pt/crash60.C: Adjust.
* g++.old-deja/g++.pt/unify6.C: Adjust.
* g++.dg/cpp0x/lambda/lambda-ice2.C: Adjust.
* g++.dg/cpp0x/nullptr15.C: Adjust.
* g++.dg/cpp0x/pr31431-2.C: Adjust.
* g++.dg/cpp0x/pr31431.C: Adjust.
* g++.dg/cpp0x/pr31434.C: Adjust.
* g++.dg/cpp0x/sfinae11.C: Adjust
* g++.dg/cpp0x/temp_default2.C: Adjust.
* g++.dg/cpp0x/trailing4.C: Adjust.
* g++.dg/cpp0x/variadic-ex3.C: Adjust.
* g++.dg/cpp0x/variadic-ex4.C: Adjust.
* g++.dg/cpp0x/variadic105.C: Adjust.
* g++.dg/cpp0x/vt-37737-2.C: Adjust.
* g++.dg/ext/vla2.C: Adjust.
* g++.dg/other/ptrmem10.C: Adjust.
* g++.dg/other/ptrmem11.C: Adjust.
* g++.dg/overload/unknown1.C: Adjust.
* g++.dg/template/conv11.C: Adjust.
* g++.dg/template/dependent-expr5.C: Adjust.
* g++.dg/template/friend.C: Adjust.
* g++.dg/template/incomplete2.C: Adjust.
* g++.dg/template/local4.C: Adjust.
* g++.dg/template/local6.C: Adjust.
* g++.dg/template/operator9.C: Adjust.
* g++.dg/template/ttp25.C: Adjust.
* g++.dg/template/unify10.C: Adjust.
* g++.dg/template/unify11.C: Adjust.
* g++.dg/template/unify6.C: Adjust.
* g++.dg/template/unify9.C: Adjust.
* g++.dg/template/varmod1.C: Adjust.
* g++.old-deja/g++.brendan/crash56.C: Adjust.
* g++.old-deja/g++.pt/crash28.C: Adjust.
* g++.old-deja/g++.pt/explicit41.C: Adjust.
* g++.old-deja/g++.pt/explicit77.C: Adjust.
* g++.old-deja/g++.pt/expr2.C: Adjust.
* g++.old-deja/g++.pt/ptrmem6.C: Adjust.
* g++.old-deja/g++.pt/spec5.C: Adjust.
* g++.old-deja/g++.pt/spec6.C: Adjust.
* g++.old-deja/g++.pt/unify4.C: Adjust.
* g++.old-deja/g++.pt/unify8.C: Adjust.
* g++.old-deja/g++.robertl/eb98.C: Adjust.
* g++.dg/overload/template5.C: New testcase.
* g++.dg/template/overload12.C: New testcase.
2011-07-11 Tobias Burnus <burnus@net-b.de> 2011-07-11 Tobias Burnus <burnus@net-b.de>
* gfortran.dg/coarray_14.f90: Remove dg-error "sorry not implemented". * gfortran.dg/coarray_14.f90: Remove dg-error "sorry not implemented".
......
...@@ -13,7 +13,7 @@ decltype (ft<F> (F())) ...@@ -13,7 +13,7 @@ decltype (ft<F> (F()))
ft() {} // { dg-error "depth" } ft() {} // { dg-error "depth" }
int main() { int main() {
ft<struct a*, 0>(); // { dg-error "no match" } ft<struct a*, 0>(); // { dg-error "no match|wrong number" }
} }
// { dg-prune-output "note" } // { dg-prune-output "note" }
...@@ -10,7 +10,7 @@ struct S { ...@@ -10,7 +10,7 @@ struct S {
static U get(const volatile T&); static U get(const volatile T&);
template<typename U> template<typename U>
static decltype(*declval<U>()) get(...); static decltype(*declval<U>()) get(...); // { dg-error "operator*" }
typedef decltype(get<T>(declval<T>())) type; // { dg-error "no match" } typedef decltype(get<T>(declval<T>())) type; // { dg-error "no match" }
}; };
......
...@@ -9,8 +9,9 @@ decltype(F()) run(F f) // { dg-message "note" } ...@@ -9,8 +9,9 @@ decltype(F()) run(F f) // { dg-message "note" }
int main() int main()
{ {
auto l = []() { return 5; }; auto l = []() { return 5; }; // { dg-error "lambda closure type" }
run(l); // { dg-error "no match" } run(l); // { dg-error "no match" }
// { dg-message "candidate" "candidate note" { target *-*-* } 14 } // { dg-message "candidate" "candidate note" { target *-*-* } 14 }
// { dg-error "use of deleted function" "candidate explanation" { target *-*-* } 5 }
} }
...@@ -17,10 +17,10 @@ void test_g() ...@@ -17,10 +17,10 @@ void test_g()
// Deduction to nullptr_t, no deduction to pointer type // Deduction to nullptr_t, no deduction to pointer type
// //
g(nullptr); // { dg-error "no matching function for call to " } g(nullptr); // { dg-error "no matching function for call to " }
// { dg-message "candidate" "candidate note" { target *-*-* } 19 } // { dg-message "(candidate|mismatched types)" "candidate note" { target *-*-* } 19 }
type_equal<float*>(g((float*)nullptr)); type_equal<float*>(g((float*)nullptr));
decltype(nullptr) mynull = 0; decltype(nullptr) mynull = 0;
g(mynull); // { dg-error "no matching function for call to " } g(mynull); // { dg-error "no matching function for call to " }
// { dg-message "candidate" "candidate note" { target *-*-* } 23 } // { dg-message "(candidate|mismatched types)" "candidate note" { target *-*-* } 23 }
type_equal<float*>(g((float*)mynull)); type_equal<float*>(g((float*)mynull));
} }
...@@ -4,5 +4,5 @@ template<typename, typename..., typename> void foo(); // { dg-message "note" } ...@@ -4,5 +4,5 @@ template<typename, typename..., typename> void foo(); // { dg-message "note" }
void bar() void bar()
{ {
foo<int>(); // { dg-error "no matching function" } foo<int>(); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 6 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 6 }
} }
...@@ -4,5 +4,5 @@ template<typename..., typename> void foo(); // { dg-message "note" } ...@@ -4,5 +4,5 @@ template<typename..., typename> void foo(); // { dg-message "note" }
void bar() void bar()
{ {
foo<int>(); // { dg-error "no matching function" } foo<int>(); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 6 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 6 }
} }
...@@ -8,5 +8,5 @@ template<typename... T> int foo(const T&) // { dg-error "not expanded with|T" } ...@@ -8,5 +8,5 @@ template<typename... T> int foo(const T&) // { dg-error "not expanded with|T" }
void bar() void bar()
{ {
foo(0); // { dg-error "no matching" } foo(0); // { dg-error "no matching" }
// { dg-message "candidate" "candidate note" { target *-*-* } 10 } // { dg-message "(candidate|cannot convert)" "candidate note" { target *-*-* } 10 }
} }
...@@ -51,6 +51,6 @@ int main() ...@@ -51,6 +51,6 @@ int main()
// static_assert( noexcept( f3(y) ), "shall be ill-formed(OK)." ); // static_assert( noexcept( f3(y) ), "shall be ill-formed(OK)." );
noexcept( f1(z) ); // { dg-message "required" } noexcept( f1(z) ); // { dg-message "required" }
static_assert( noexcept( f2(z) ), "shall be ill-formed." ); // { dg-error "no match" } static_assert( noexcept( f2(z) ), "shall be ill-formed." ); // { dg-error "no match|could not convert" }
noexcept( f3(z) ); // { dg-message "required" } noexcept( f3(z) ); // { dg-message "required" }
} }
...@@ -32,7 +32,7 @@ struct S { ...@@ -32,7 +32,7 @@ struct S {
template<class... U, template<class... U,
typename enable_if<and_<is_same<T, U>...>::value>::type*& = enabler typename enable_if<and_<is_same<T, U>...>::value>::type*& = enabler
> >
S(U...){} // # S(U...){} // { dg-error "no type named 'type'" }
}; };
S<bool> s(0); // { dg-error "no match" } S<bool> s(0); // { dg-error "no match" }
...@@ -8,7 +8,7 @@ void g() ...@@ -8,7 +8,7 @@ void g()
f(1, 'c'); // f<int,char>(1,'c') f(1, 'c'); // f<int,char>(1,'c')
f(1); // f<int,double>(1,0) f(1); // f<int,double>(1,0)
f(); // { dg-error "no matching function" } f(); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 10 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 10 }
f<int>(); // f<int,double>(0,0) f<int>(); // f<int,double>(0,0)
f<int,char>(); // f<int,char>(0,0) f<int,char>(); // f<int,char>(0,0)
} }
...@@ -8,5 +8,5 @@ auto f(T,U) -> decltype(T() + U()) ...@@ -8,5 +8,5 @@ auto f(T,U) -> decltype(T() + U())
template<class T> void g(T){} // { dg-message "note" } template<class T> void g(T){} // { dg-message "note" }
int main() { g(f); } // { dg-error "no matching function" } int main() { g(f); } // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 10 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 10 }
...@@ -4,8 +4,8 @@ void g() ...@@ -4,8 +4,8 @@ void g()
{ {
int i = f<int>(5.6); int i = f<int>(5.6);
int j = f(5.6); // { dg-error "no matching" } int j = f(5.6); // { dg-error "no matching" }
// { dg-message "candidate" "candidate note" { target *-*-* } 6 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 6 }
f<void>(f<int, bool>); f<void>(f<int, bool>);
f<void>(f<int>); // { dg-error "no matching" } f<void>(f<int>); // { dg-error "no matching" }
// { dg-message "candidate" "candidate note" { target *-*-* } 9 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 9 }
} }
...@@ -8,6 +8,6 @@ void g() ...@@ -8,6 +8,6 @@ void g()
f<int>("aa",3.0); // Y is deduced to be char*, and f<int>("aa",3.0); // Y is deduced to be char*, and
// Z is deduced to be double // Z is deduced to be double
f("aa",3.0); // { dg-error "no matching" } f("aa",3.0); // { dg-error "no matching" }
// { dg-message "candidate" "candidate note" { target *-*-* } 10 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 10 }
f2<char, short, int, long>(); // okay f2<char, short, int, long>(); // okay
} }
...@@ -21,4 +21,5 @@ struct call_sum { ...@@ -21,4 +21,5 @@ struct call_sum {
int main() { int main() {
// This shouldn't be an error; this is bug 35722. // This shouldn't be an error; this is bug 35722.
reverse<call_sum>(1,2); // { dg-bogus "no match" "" { xfail *-*-* } } reverse<call_sum>(1,2); // { dg-bogus "no match" "" { xfail *-*-* } }
// { dg-bogus "sorry, unimplemented" "candidate explanation" { xfail *-*-* } 6 }
} }
...@@ -4,7 +4,7 @@ template<class U, class... T> ...@@ -4,7 +4,7 @@ template<class U, class... T>
void f() // { dg-message "note" } void f() // { dg-message "note" }
{ {
f<T...>(); // { dg-error "no matching" } f<T...>(); // { dg-error "no matching" }
// { dg-message "candidate" "candidate note" { target *-*-* } 6 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 6 }
} }
template<> template<>
......
...@@ -15,5 +15,5 @@ void bar(int i) ...@@ -15,5 +15,5 @@ void bar(int i)
char d[i] ; char d[i] ;
begin(d); // { dg-error "no matching function" "" } begin(d); // { dg-error "no matching function" "" }
// { dg-message "candidate" "candidate note" { target *-*-* } 17 } // { dg-message "(candidate|valid template argument)" "candidate note" { target *-*-* } 17 }
} }
...@@ -13,7 +13,7 @@ template <class C> ...@@ -13,7 +13,7 @@ template <class C>
static void static void
bar(C *c, void (C::*m) ()) bar(C *c, void (C::*m) ())
{ {
foo<C,m>((void *)c);// { dg-error "(not a valid template arg|pointer-to-member|no matching fun)" } foo<C,m>((void *)c);// { dg-error "(not a valid template arg|pointer-to-member|no matching fun|could not convert)" }
// { dg-message "candidate" "candidate note" { target *-*-* } 16 } // { dg-message "candidate" "candidate note" { target *-*-* } 16 }
} }
......
...@@ -14,7 +14,7 @@ template <typename T> ...@@ -14,7 +14,7 @@ template <typename T>
int int
bar(int T::* p) bar(int T::* p)
{ {
return foo<p>(0);// { dg-error "(not a valid template arg|no matching func|pointer-to-member)" } return foo<p>(0);// { dg-error "(not a valid template arg|no matching func|pointer-to-member|could not convert)" }
// { dg-message "candidate" "candidate note" { target *-*-* } 17 } // { dg-message "candidate" "candidate note" { target *-*-* } 17 }
} }
......
// { dg-do compile }
template<typename T>
int low(T a, T b, T c) { return a + b + c; } // { dg-message "template" }
template<typename T>
int high(T a, T b, T c) { return a + b + c; } // { dg-message "template" }
int test (void)
{
low (5, 6); // { dg-error "no matching function" }
// { dg-message "(candidate|3 arguments, 2 provided)" "" { target *-*-* } 11 }
high (5, 6, 7, 8); // { dg-error "no matching function" }
// { dg-message "(candidate|3 arguments, 4 provided)" "" { target *-*-* } 13 }
}
...@@ -6,5 +6,5 @@ template <typename T> void bar(T f); // { dg-message "note" } ...@@ -6,5 +6,5 @@ template <typename T> void bar(T f); // { dg-message "note" }
void baz() { void baz() {
bar(foo); // { dg-error "<unresolved overloaded function type>" } bar(foo); // { dg-error "<unresolved overloaded function type>" }
// { dg-message "candidate" "candidate note" { target *-*-* } 8 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 8 }
} }
...@@ -7,5 +7,5 @@ struct A ...@@ -7,5 +7,5 @@ struct A
int main() int main()
{ {
A().operator int(); // { dg-error "operator int" } A().operator int(); // { dg-error "operator int" }
// { dg-message "candidate" "candidate note" { target *-*-* } 9 } // { dg-message "(candidate|mismatched types)" "candidate note" { target *-*-* } 9 }
} }
...@@ -4,8 +4,8 @@ void f(int, T (*)() = 0); // { dg-message "note" } ...@@ -4,8 +4,8 @@ void f(int, T (*)() = 0); // { dg-message "note" }
void g() { void g() {
typedef int A[2]; typedef int A[2];
f<A>(0); // { dg-error "" } f<A>(0); // { dg-error "" }
// { dg-message "candidate" "candidate note" { target *-*-* } 6 } // { dg-error "returning an array" "candidate explanation" { target *-*-* } 2 }
typedef void F(); typedef void F();
f<F>(0); // { dg-error "" } f<F>(0); // { dg-error "" }
// { dg-message "candidate" "candidate note" { target *-*-* } 9 } // { dg-error "returning a function" "candidate explanation" { target *-*-* } 2 }
} }
...@@ -40,12 +40,12 @@ struct foo { ...@@ -40,12 +40,12 @@ struct foo {
bind (&bar::baikt); bind (&bar::baikt);
bind (&barf); // { dg-error "no matching function" } bind (&barf); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 42 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 42 }
bind (&foo::barf); // { dg-error "no matching function" } bind (&foo::barf); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 44 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 44 }
bindm (&barf); // { dg-error "no matching function" } bindm (&barf); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 47 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 47 }
bindm (&foo::barf); bindm (&foo::barf);
bindn (&barf); bindn (&barf);
...@@ -53,15 +53,15 @@ struct foo { ...@@ -53,15 +53,15 @@ struct foo {
bindb (&barf); bindb (&barf);
bindb (&foo::barf); // { dg-error "ambiguous" } bindb (&foo::barf); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 55 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 55 }
bind (&bark); // { dg-error "no matching function" } bind (&bark); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 58 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 58 }
bind (&bar::bark); // { dg-error "no matching function" } bind (&bar::bark); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 60 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 60 }
bindm (&bark); // { dg-error "no matching function" } bindm (&bark); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 63 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 63 }
bindm (&bar::bark); bindm (&bar::bark);
bindn (&bark); bindn (&bark);
...@@ -69,7 +69,7 @@ struct foo { ...@@ -69,7 +69,7 @@ struct foo {
bindb (&bark); bindb (&bark);
bindb (&bar::bark); // { dg-error "ambiguous" } bindb (&bar::bark); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 71 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 71 }
} }
}; };
...@@ -92,12 +92,12 @@ struct foo { ...@@ -92,12 +92,12 @@ struct foo {
bind (&barT::baikt); bind (&barT::baikt);
bind (&barf); // { dg-error "no matching function" } bind (&barf); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 94 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 94 }
bind (&foo::barf); // { dg-error "no matching function" } bind (&foo::barf); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 96 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 96 }
bindm (&barf); // { dg-error "no matching function" } bindm (&barf); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 99 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 99 }
bindm (&foo::barf); bindm (&foo::barf);
bindn (&barf); bindn (&barf);
...@@ -105,15 +105,15 @@ struct foo { ...@@ -105,15 +105,15 @@ struct foo {
bindb (&barf); bindb (&barf);
bindb (&foo::barf); // { dg-error "ambiguous" } bindb (&foo::barf); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 107 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 107 }
bind (&bark); // { dg-error "no matching function" } bind (&bark); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 110 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 110 }
bind (&barT::bark); // { dg-error "no matching function" } bind (&barT::bark); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 112 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 112 }
bindm (&bark); // { dg-error "no matching function" } bindm (&bark); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 115 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 115 }
bindm (&barT::bark); bindm (&barT::bark);
bindn (&bark); bindn (&bark);
...@@ -121,7 +121,7 @@ struct foo { ...@@ -121,7 +121,7 @@ struct foo {
bindb (&bark); bindb (&bark);
bindb (&barT::bark); // { dg-error "ambiguous" } bindb (&barT::bark); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 123 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 123 }
} }
}; };
......
...@@ -11,7 +11,7 @@ struct enable_if< true, T > ...@@ -11,7 +11,7 @@ struct enable_if< true, T >
template < typename T > template < typename T >
struct enable_if< true, T >::type struct enable_if< true, T >::type
f( T x ); f( T x ); // { dg-error "not a class type" }
void void
g( void ) g( void )
......
...@@ -26,5 +26,5 @@ int main() ...@@ -26,5 +26,5 @@ int main()
{ {
s<int>::t y; s<int>::t y;
cout << y; // { dg-error "" } cout << y; // { dg-error "" }
// { dg-message "candidate" "candidate note" { target *-*-* } 28 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 28 }
} }
...@@ -9,6 +9,6 @@ A a; // { dg-error "incomplete type" } ...@@ -9,6 +9,6 @@ A a; // { dg-error "incomplete type" }
void bar() void bar()
{ {
foo<a>(); // { dg-error "no matching function" } foo<a>(); // { dg-error "(no matching function|could not convert)" }
// { dg-message "candidate" "candidate note" { target *-*-* } 12 } // { dg-message "candidate" "candidate note" { target *-*-* } 12 }
} }
...@@ -5,6 +5,6 @@ template <typename T> void foo() {} // { dg-message "note" } ...@@ -5,6 +5,6 @@ template <typename T> void foo() {} // { dg-message "note" }
int main () { int main () {
struct S {}; struct S {};
foo<S> (); // { dg-error "match" } foo<S> (); // { dg-error "(match|template argument for|trying to instantiate)" }
// { dg-message "candidate" "candidate note" { target *-*-* } 8 } // { dg-message "candidate" "candidate note" { target *-*-* } 8 }
} }
...@@ -5,7 +5,7 @@ template <class T> struct PCVector2 // { dg-message "note" } ...@@ -5,7 +5,7 @@ template <class T> struct PCVector2 // { dg-message "note" }
PCVector2<T> operator- (const PCVector2<T> &ov) const PCVector2<T> operator- (const PCVector2<T> &ov) const
{ {
return PCVector2<T>(ov.xFIELD, ov.yFIELD); // { dg-error "matching" } return PCVector2<T>(ov.xFIELD, ov.yFIELD); // { dg-error "matching" }
// { dg-message "candidate" "candidate note" { target *-*-* } 7 } // { dg-message "(candidate|expects 1 argument, 2 provided|cannot convert)" "candidate note" { target *-*-* } 7 }
} }
T xFIELD, yFIELD; T xFIELD, yFIELD;
......
...@@ -5,6 +5,6 @@ template<operator+> void foo(); // { dg-error "before|non-function|template" } ...@@ -5,6 +5,6 @@ template<operator+> void foo(); // { dg-error "before|non-function|template" }
void bar() void bar()
{ {
foo(); // { dg-error "no matching function" } foo(); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 7 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 7 }
} }
// { dg-do compile }
struct S {int x; int y;};
template<typename T>
int foo(T a, T b) {return a + b;} // { dg-message "template" }
template<typename T, typename T2>
int foo(T a, T2& b, T2 c) {return a + b;} // { dg-message "template" }
int foo(char*, S&); // { dg-message "foo" }
// { dg-message "candidate expects 2 arguments, 3 provided" "arity" { target *-*-* } 8 }
int foo2(int x)
{
S s={1,2};
char c;
foo(c, 2, c); // { dg-error "no matching function" }
// { dg-message "(candidate|deduced conflicting types for)" "candidate note" { target *-*-* } 15 }
}
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
struct A {}; struct A {};
template <typename T> T A::* Foo (); // { dg-message "note" } template <typename T> T A::* Foo (); // { dg-error "reference" }
void Baz () void Baz ()
{ {
......
...@@ -8,7 +8,7 @@ template<int T> struct cl { ...@@ -8,7 +8,7 @@ template<int T> struct cl {
const static int value = T; const static int value = T;
}; };
template<int I> void fn (char (*) [cl<I>::value] = 0 ); // { dg-message "note" } template<int I> void fn (char (*) [cl<I>::value] = 0 ); // { dg-error "zero-size array" }
void foo (void) void foo (void)
{ {
......
...@@ -18,12 +18,12 @@ void f4(T, C<5>); // { dg-message "note" } ...@@ -18,12 +18,12 @@ void f4(T, C<5>); // { dg-message "note" }
template<int N> struct X {}; template<int N> struct X {};
void g() { void g() {
f1(5l, X<5>()); // { dg-error "no matching" } f1(5l, X<5>()); // { dg-error "no matching" }
// { dg-message "candidate" "candidate note" { target *-*-* } 20 } // { dg-message "(candidate|inconsistent with)" "candidate note" { target *-*-* } 20 }
f2(X<5>(), 5); f2(X<5>(), 5);
f3(X<5>(), 5l); // { dg-error "no matching" } f3(X<5>(), 5l); // { dg-error "no matching" }
// { dg-message "candidate" "candidate note" { target *-*-* } 23 } // { dg-message "(candidate|inconsistent with)" "candidate note" { target *-*-* } 23 }
f4(5, X<5>()); f4(5, X<5>());
f4(5l, X<5>()); // { dg-error "no matching" } f4(5l, X<5>()); // { dg-error "no matching" }
// { dg-message "candidate" "candidate note" { target *-*-* } 26 } // { dg-message "(candidate|inconsistent with)" "candidate note" { target *-*-* } 26 }
f4((short)5, X<5>()); f4((short)5, X<5>());
} }
...@@ -26,34 +26,34 @@ void cvFunction(void (CLASS::* method)() const volatile) {} // { dg-message "not ...@@ -26,34 +26,34 @@ void cvFunction(void (CLASS::* method)() const volatile) {} // { dg-message "not
int main() { int main() {
mFunction(&MyClass::mMethod); mFunction(&MyClass::mMethod);
mFunction(&MyClass::cMethod); // { dg-error "no matching function" } mFunction(&MyClass::cMethod); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 28 } // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 28 }
mFunction(&MyClass::vMethod); // { dg-error "no matching function" } mFunction(&MyClass::vMethod); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 30 } // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 30 }
mFunction(&MyClass::cvMethod); // { dg-error "no matching function" } mFunction(&MyClass::cvMethod); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 32 } // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 32 }
cFunction(&MyClass::mMethod); // { dg-error "no matching function" } cFunction(&MyClass::mMethod); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 35 } // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 35 }
cFunction(&MyClass::cMethod); cFunction(&MyClass::cMethod);
cFunction(&MyClass::vMethod); // { dg-error "no matching function" } cFunction(&MyClass::vMethod); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 38 } // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 38 }
cFunction(&MyClass::cvMethod); // { dg-error "no matching function" } cFunction(&MyClass::cvMethod); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 40 } // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 40 }
vFunction(&MyClass::mMethod); // { dg-error "no matching function" } vFunction(&MyClass::mMethod); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 43 } // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 43 }
vFunction(&MyClass::cMethod); // { dg-error "no matching function" } vFunction(&MyClass::cMethod); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 45 } // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 45 }
vFunction(&MyClass::vMethod); vFunction(&MyClass::vMethod);
vFunction(&MyClass::cvMethod); // { dg-error "no matching function" } vFunction(&MyClass::cvMethod); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 48 } // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 48 }
cvFunction(&MyClass::mMethod); // { dg-error "no matching function" } cvFunction(&MyClass::mMethod); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 51 } // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 51 }
cvFunction(&MyClass::cMethod); // { dg-error "no matching function" } cvFunction(&MyClass::cMethod); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 53 } // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 53 }
cvFunction(&MyClass::vMethod); // { dg-error "no matching function" } cvFunction(&MyClass::vMethod); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 55 } // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 55 }
cvFunction(&MyClass::cvMethod); cvFunction(&MyClass::cvMethod);
return 0; return 0;
......
...@@ -20,7 +20,7 @@ struct B ...@@ -20,7 +20,7 @@ struct B
C (U t) C (U t)
{ {
A a; A a;
A b = foo (this, a, t); // { dg-error "no matching function" } A b = foo (this, a, t); // { dg-error "(no matching function|is not a)" }
// { dg-message "candidate" "candidate note" { target *-*-* } 23 } // { dg-message "candidate" "candidate note" { target *-*-* } 23 }
} }
} c; } c;
......
...@@ -19,5 +19,5 @@ void Bar () ...@@ -19,5 +19,5 @@ void Bar ()
Foo3 (&Baz); Foo3 (&Baz);
Foo3 (&Baz, &Baz); // { dg-error "no matching function" "" } Foo3 (&Baz, &Baz); // { dg-error "no matching function" "" }
// { dg-message "candidate" "candidate note" { target *-*-* } 21 } // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 21 }
} }
...@@ -11,5 +11,5 @@ int main() ...@@ -11,5 +11,5 @@ int main()
{ {
Foo (f); Foo (f);
Baz (f); // { dg-error "no matching function" "" } Baz (f); // { dg-error "no matching function" "" }
// { dg-message "candidate" "candidate note" { target *-*-* } 13 } // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 13 }
} }
...@@ -14,5 +14,5 @@ const X *x; ...@@ -14,5 +14,5 @@ const X *x;
int main () { int main () {
f (*x, &X::g); // { dg-error "no matching function" } f (*x, &X::g); // { dg-error "no matching function" }
// { dg-message "candidate" "candidate note" { target *-*-* } 16 } // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 16 }
} }
...@@ -7,5 +7,5 @@ void bar() ...@@ -7,5 +7,5 @@ void bar()
int i; int i;
int A[i][i]; int A[i][i];
foo(A); // { dg-error "" } foo(A); // { dg-error "" }
// { dg-message "candidate" "candidate note" { target *-*-* } 9 } // { dg-message "(candidate|not a valid template argument)" "candidate note" { target *-*-* } 9 }
} }
...@@ -278,7 +278,7 @@ SetLD<T>::remove(const T& item) ...@@ -278,7 +278,7 @@ SetLD<T>::remove(const T& item)
Vix x; Vix x;
for (first(x); 0 != x && this->REMOVE_CURRENT != a; next(x, a)) for (first(x); 0 != x && this->REMOVE_CURRENT != a; next(x, a))
a = operator()(x) == item ? this->REMOVE_CURRENT: this->NORMAL; // { dg-error "" } .* a = operator()(x) == item ? this->REMOVE_CURRENT: this->NORMAL; // { dg-error "" } .*
// { dg-message "candidate" "candidate note" { target *-*-* } 280 } // { dg-message "(candidate|not derived from)" "candidate note" { target *-*-* } 280 }
} }
template<class T> template<class T>
bool bool
...@@ -287,7 +287,7 @@ SetLD<T>::contains(const T& item) const ...@@ -287,7 +287,7 @@ SetLD<T>::contains(const T& item) const
Vix x; Vix x;
for (first(x); 0 != x; next(x)) { for (first(x); 0 != x; next(x)) {
if (operator()(x) == item)// { dg-error "" } .* if (operator()(x) == item)// { dg-error "" } .*
// { dg-message "candidate" "candidate note" { target *-*-* } 289 } // { dg-message "(candidate|not derived from)" "candidate note" { target *-*-* } 289 }
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
......
...@@ -11,5 +11,5 @@ void f(unsigned int n) { ...@@ -11,5 +11,5 @@ void f(unsigned int n) {
int x[n]; int x[n];
asize(x); // { dg-error "" } no matching function asize(x); // { dg-error "" } no matching function
// { dg-message "candidate" "candidate note" { target *-*-* } 13 } // { dg-message "(candidate|not a valid template argument)" "candidate note" { target *-*-* } 13 }
} }
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
template< typename SID, class SDR > template< typename SID, class SDR >
void k( SID sid, SDR* p, void k( SID sid, SDR* p,
void (SDR::*) void (SDR::*)
( typename SID::T ) ); // { dg-message "note" } ( typename SID::T ) ); // { dg-error "no type named 'T'" }
struct E { }; struct E { };
struct S { void f( int ); }; struct S { void f( int ); };
......
// { dg-do assemble } // { dg-do assemble }
template <int I> template <int I>
void f(int i); // { dg-message "note" } void f(int i); // { dg-message "void f" }
void g() void g()
{ {
......
...@@ -15,5 +15,5 @@ void g() { ...@@ -15,5 +15,5 @@ void g() {
f<0>(s0, s2); f<0>(s0, s2);
f(s0, s2); // { dg-error "" } no matching function f(s0, s2); // { dg-error "" } no matching function
// { dg-message "candidate" "candidate note" { target *-*-* } 17 } // { dg-message "(candidate|deduced conflicting types|ambiguous base class)" "candidate note" { target *-*-* } 17 }
} }
...@@ -9,5 +9,5 @@ void foo(S<J + 2>); // { dg-message "note" } ...@@ -9,5 +9,5 @@ void foo(S<J + 2>); // { dg-message "note" }
void bar() void bar()
{ {
foo(S<3>()); // { dg-error "" } no way to deduce J from this. foo(S<3>()); // { dg-error "" } no way to deduce J from this.
// { dg-message "candidate" "candidate note" { target *-*-* } 11 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 11 }
} }
...@@ -13,9 +13,9 @@ public: ...@@ -13,9 +13,9 @@ public:
}; };
template <void (A::*)() > template <void (A::*)() >
void g() {} // { dg-message "note" } void g() {} // { dg-message "void g" }
template <int A::*> template <int A::*>
void h() {} // { dg-message "note" } void h() {} // { dg-message "void h" }
int main() { int main() {
......
...@@ -14,9 +14,9 @@ template void g(int i, int j); ...@@ -14,9 +14,9 @@ template void g(int i, int j);
void h() void h()
{ {
f(3, 'c'); // { dg-error "" } no matching function f(3, 'c'); // { dg-error "" } no matching function
// { dg-message "candidate" "candidate note" { target *-*-* } 16 } // { dg-message "(candidate|deduced conflicting types)" "candidate note" { target *-*-* } 16 }
g(3, 'c'); // { dg-error "" } no matching function g(3, 'c'); // { dg-error "" } no matching function
// { dg-message "candidate" "candidate note" { target *-*-* } 18 } // { dg-message "(candidate|deduced conflicting types)" "candidate note" { target *-*-* } 18 }
} }
...@@ -25,9 +25,9 @@ void h() ...@@ -25,9 +25,9 @@ void h()
{ {
S1 s1; S1 s1;
s1.f(3, 'c'); // { dg-error "" } no matching function s1.f(3, 'c'); // { dg-error "" } no matching function
// { dg-message "candidate" "candidate note" { target *-*-* } 27 } // { dg-message "(candidate|deduced conflicting types)" "candidate note" { target *-*-* } 27 }
S2<char> s2; S2<char> s2;
s2.f(3, 'c'); // { dg-error "" } no matching function s2.f(3, 'c'); // { dg-error "" } no matching function
// { dg-message "candidate" "candidate note" { target *-*-* } 31 } // { dg-message "(candidate|deduced conflicting types)" "candidate note" { target *-*-* } 31 }
} }
...@@ -8,6 +8,6 @@ int ...@@ -8,6 +8,6 @@ int
main () main ()
{ {
f (g); // { dg-error "" } ambiguous unification f (g); // { dg-error "" } ambiguous unification
// { dg-message "candidate" "candidate note" { target *-*-* } 10 } // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 10 }
return 0; return 0;
} }
...@@ -19,7 +19,7 @@ template<> void fn<int &>() {} // ok, specialize A ...@@ -19,7 +19,7 @@ template<> void fn<int &>() {} // ok, specialize A
template<> void fn<void ()>() {} // ok, specialize A template<> void fn<void ()>() {} // ok, specialize A
// now make sure we moan when we really should // now make sure we moan when we really should
template<class T> void foo(T const *){} // { dg-message "note" } template<class T> void foo(T const *){} // { dg-error "pointer to reference" }
void f() void f()
{ {
......
...@@ -16,6 +16,6 @@ void Foo (float); // { dg-message "note" } candidate ...@@ -16,6 +16,6 @@ void Foo (float); // { dg-message "note" } candidate
void baz (int **p1) void baz (int **p1)
{ {
Foo (p1); // { dg-error "match" } no such function Foo (p1); // { dg-error "match" } no such function
// { dg-message "candidate" "candidate note" { target *-*-* } 18 } // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 18 }
Bar (p1); // OK Bar (p1); // OK
} }
...@@ -15,5 +15,5 @@ ...@@ -15,5 +15,5 @@
void f() void f()
{ {
extent(b); // { dg-error "" } no matching function extent(b); // { dg-error "" } no matching function
// { dg-message "candidate" "candidate note" { target *-*-* } 17 } // { dg-message "(candidate|mismatched types)" "candidate note" { target *-*-* } 17 }
} }
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