aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Froyd <froydnj@codesourcery.com>2011-07-17 02:34:10 +0000
committerJason Merrill <jason@gcc.gnu.org>2011-07-16 22:34:10 -0400
commit3d2f6864225cc660adfc9136c859dd26e2a40135 (patch)
tree8686f4122e795ce6ee0e3abdbf5a370034464f27
parentc6f4a801a697e19df5560fb79b91fe7ee77a1cca (diff)
downloadgcc-3d2f6864225cc660adfc9136c859dd26e2a40135.zip
gcc-3d2f6864225cc660adfc9136c859dd26e2a40135.tar.gz
gcc-3d2f6864225cc660adfc9136c859dd26e2a40135.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog57
-rw-r--r--gcc/cp/call.c144
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/pt.c683
-rw-r--r--gcc/testsuite/ChangeLog58
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/decltype29.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/error4.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice2.C3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nullptr15.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr31431-2.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr31431.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr31434.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/sfinae11.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/sfinae26.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/temp_default2.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/trailing4.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic-ex3.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic-ex4.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/variadic105.C1
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/vt-37737-2.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/vla2.C2
-rw-r--r--gcc/testsuite/g++.dg/other/ptrmem10.C2
-rw-r--r--gcc/testsuite/g++.dg/other/ptrmem11.C2
-rw-r--r--gcc/testsuite/g++.dg/overload/template5.C15
-rw-r--r--gcc/testsuite/g++.dg/overload/unknown1.C2
-rw-r--r--gcc/testsuite/g++.dg/template/conv11.C2
-rw-r--r--gcc/testsuite/g++.dg/template/deduce3.C4
-rw-r--r--gcc/testsuite/g++.dg/template/dependent-expr5.C32
-rw-r--r--gcc/testsuite/g++.dg/template/error45.C2
-rw-r--r--gcc/testsuite/g++.dg/template/friend.C2
-rw-r--r--gcc/testsuite/g++.dg/template/incomplete2.C2
-rw-r--r--gcc/testsuite/g++.dg/template/local4.C2
-rw-r--r--gcc/testsuite/g++.dg/template/local6.C2
-rw-r--r--gcc/testsuite/g++.dg/template/operator9.C2
-rw-r--r--gcc/testsuite/g++.dg/template/overload12.C17
-rw-r--r--gcc/testsuite/g++.dg/template/ptrmem2.C2
-rw-r--r--gcc/testsuite/g++.dg/template/sfinae2.C2
-rw-r--r--gcc/testsuite/g++.dg/template/ttp25.C6
-rw-r--r--gcc/testsuite/g++.dg/template/unify10.C24
-rw-r--r--gcc/testsuite/g++.dg/template/unify11.C2
-rw-r--r--gcc/testsuite/g++.dg/template/unify6.C2
-rw-r--r--gcc/testsuite/g++.dg/template/unify7.C2
-rw-r--r--gcc/testsuite/g++.dg/template/unify9.C2
-rw-r--r--gcc/testsuite/g++.dg/template/varmod1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash56.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/crash28.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/crash60.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/explicit41.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/explicit77.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/expr2.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/spec5.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/spec6.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/unify4.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/unify6.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/unify8.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb98.C2
58 files changed, 872 insertions, 277 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index bb503c3..4db0c7e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,60 @@
+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>
* Make-lang.in (check-g++-strict-gc): New.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 56f3408..99f9cc3 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -434,7 +434,10 @@ enum rejection_reason_code {
rr_arity,
rr_explicit_conversion,
rr_arg_conversion,
- rr_bad_arg_conversion
+ rr_bad_arg_conversion,
+ rr_template_unification,
+ rr_template_instantiation,
+ rr_invalid_copy
};
struct conversion_info {
@@ -462,6 +465,24 @@ struct rejection_reason {
struct conversion_info conversion;
/* Same, but for bad argument conversions. */
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;
};
@@ -622,6 +643,50 @@ explicit_conversion_rejection (tree from, tree to)
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. */
static conversion *
@@ -2859,6 +2924,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
int i;
tree fn;
struct rejection_reason *reason = NULL;
+ int errs;
/* We don't do deduction on the in-charge parameter, the VTT
parameter or 'this'. */
@@ -2901,17 +2967,31 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
}
gcc_assert (ia == nargs_without_in_chrg);
+ errs = errorcount+sorrycount;
i = fn_type_unification (tmpl, explicit_targs, targs,
args_without_in_chrg,
nargs_without_in_chrg,
- return_type, strict, flags);
+ return_type, strict, flags, false);
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);
if (fn == error_mark_node)
- goto fail;
+ {
+ reason = template_instantiation_rejection (tmpl, targs);
+ goto fail;
+ }
/* In [class.copy]:
@@ -2940,7 +3020,10 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn);
if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)),
ctype))
- goto fail;
+ {
+ reason = invalid_copy_with_fn_template_rejection ();
+ goto fail;
+ }
}
if (obj != NULL_TREE)
@@ -3108,6 +3191,18 @@ print_conversion_rejection (location_t loc, struct conversion_info *info)
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
is the text to print before the candidate itself.
@@ -3154,10 +3249,8 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate)
switch (r->code)
{
case rr_arity:
- inform_n (loc, r->u.arity.expected,
- " candidate expects %d argument, %d provided",
- " candidate expects %d arguments, %d provided",
- r->u.arity.expected, r->u.arity.actual);
+ print_arity_information (loc, r->u.arity.actual,
+ r->u.arity.expected);
break;
case rr_arg_conversion:
print_conversion_rejection (loc, &r->u.conversion);
@@ -3171,6 +3264,39 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate)
"conversion", r->u.conversion.from_type,
r->u.conversion.to_type);
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:
default:
/* This candidate didn't have any issues or we failed to
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 7de104d..61c1380 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -6570,7 +6570,7 @@ resolve_address_of_overloaded_function (tree target_type,
targs = make_tree_vec (DECL_NTPARMS (fn));
if (fn_type_unification (fn, explicit_targs, targs, args, nargs,
target_ret_type, DEDUCE_EXACT,
- LOOKUP_NORMAL))
+ LOOKUP_NORMAL, false))
/* Argument deduction failed. */
continue;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 96d9fa8..c590585 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5161,7 +5161,8 @@ extern tree instantiate_class_template (tree);
extern tree instantiate_template (tree, tree, tsubst_flags_t);
extern int fn_type_unification (tree, tree, tree,
const tree *, unsigned int,
- tree, unification_kind_t, int);
+ tree, unification_kind_t, int,
+ bool);
extern void mark_decl_instantiated (tree, int);
extern int more_specialized_fn (tree, tree, int);
extern void do_decl_instantiation (tree, tree);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d50e214..a93f677 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -109,15 +109,22 @@ static GTY(()) VEC(tree,gc) *canonical_template_parms;
#define UNIFY_ALLOW_OUTER_MORE_CV_QUAL 32
#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 pop_access_scope (tree);
static void push_deduction_access_scope (tree);
static void pop_deduction_access_scope (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,
- unification_kind_t, int, bool);
-static int unify (tree, tree, tree, tree, int);
+ unification_kind_t, int, bool, bool);
+static int unify (tree, tree, tree, tree, int, bool);
static void add_pending_template (tree);
static tree reopen_tinst_level (struct tinst_level *);
static tree tsubst_initializer_list (tree, tree);
@@ -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*,
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 tree convert_nontype_argument_function (tree, tree);
static tree convert_nontype_argument (tree, tree, tsubst_flags_t);
@@ -156,7 +164,8 @@ static tree get_bindings (tree, tree, tree, bool);
static int template_decl_level (tree);
static int check_cv_quals_for_unify (int, tree, tree);
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_args (tree, tree, tsubst_flags_t, tree);
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);
static bool check_specialization_scope (void);
static tree process_partial_specialization (tree);
static void set_current_access_from_decl (tree);
-static tree get_template_base (tree, tree, tree, tree);
-static tree try_class_unification (tree, tree, tree, tree);
+static enum template_base_result get_template_base (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,
tree, tree);
static bool template_template_parm_bindings_ok_p (tree, tree);
@@ -5267,6 +5277,211 @@ has_value_dependent_address (tree op)
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
indicated TYPE. If the conversion is successful, return the
converted value. If the conversion is unsuccessful, return
@@ -6550,11 +6765,13 @@ template_args_equal (tree ot, tree nt)
return cp_tree_equal (ot, nt);
}
-/* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets
- of template arguments. Returns 0 otherwise. */
+/* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets of
+ template arguments. Returns 0 otherwise, and updates OLDARG_PTR and
+ NEWARG_PTR with the offending arguments if they are non-NULL. */
-int
-comp_template_args (tree oldargs, tree newargs)
+static int
+comp_template_args_with_info (tree oldargs, tree newargs,
+ tree *oldarg_ptr, tree *newarg_ptr)
{
int i;
@@ -6567,11 +6784,26 @@ comp_template_args (tree oldargs, tree newargs)
tree ot = TREE_VEC_ELT (oldargs, i);
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;
}
+/* 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
add_pending_template (tree d)
{
@@ -13724,7 +13956,7 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
This is, of course, not reentrant. */
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 int deduction_depth;
@@ -13748,7 +13980,7 @@ deduction_tsubst_fntype (tree fn, tree targs)
input_location = DECL_SOURCE_LOCATION (fn);
++deduction_depth;
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);
--deduction_depth;
@@ -13961,7 +14193,8 @@ fn_type_unification (tree fn,
unsigned int nargs,
tree return_type,
unification_kind_t strict,
- int flags)
+ int flags,
+ bool explain_p)
{
tree parms;
tree fntype;
@@ -13996,12 +14229,15 @@ fn_type_unification (tree fn,
bool incomplete = false;
if (explicit_targs == error_mark_node)
- return 1;
+ return unify_invalid (explain_p);
converted_args
- = (coerce_template_parms (tparms, explicit_targs, NULL_TREE, tf_none,
- /*require_all_args=*/false,
- /*use_default_args=*/false));
+ = (coerce_template_parms (tparms, explicit_targs, NULL_TREE,
+ (explain_p
+ ? tf_warning_or_error
+ : tf_none),
+ /*require_all_args=*/false,
+ /*use_default_args=*/false));
if (converted_args == error_mark_node)
return 1;
@@ -14060,7 +14296,10 @@ fn_type_unification (tree fn,
incomplete = NUM_TMPL_ARGS (explicit_targs) != NUM_TMPL_ARGS (targs);
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;
if (fntype == error_mark_node)
@@ -14092,7 +14331,7 @@ fn_type_unification (tree fn,
event. */
result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
targs, parms, args, nargs, /*subr=*/0,
- strict, flags);
+ strict, flags, explain_p);
/* Now that we have bindings for all of the template arguments,
ensure that the arguments deduced for the template template
@@ -14118,7 +14357,7 @@ fn_type_unification (tree fn,
if (result == 0
&& !template_template_parm_bindings_ok_p
(DECL_INNERMOST_TEMPLATE_PARMS (fn), targs))
- return 1;
+ return unify_inconsistent_template_template_parameters (explain_p);
if (result == 0)
/* All is well so far. Now, check:
@@ -14131,7 +14370,10 @@ fn_type_unification (tree fn,
substitution results in an invalid type, as described above,
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)
return 1;
@@ -14148,7 +14390,8 @@ fn_type_unification (tree fn,
sarg = tree_cons (NULL_TREE, TREE_TYPE (substed), sarg);
for (i = 0; i < nargs && sarg; ++i, sarg = TREE_CHAIN (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,
unsigned int xnargs,
int subr,
unification_kind_t strict,
- int flags)
+ int flags,
+ bool explain_p)
{
tree parm, arg, arg_expr;
int i;
@@ -14350,7 +14594,7 @@ type_unification_real (tree tparms,
arg_expr = NULL;
if (arg == error_mark_node)
- return 1;
+ return unify_invalid (explain_p);
if (arg == unknown_type_node)
/* We can't deduce anything from this, but we might get all the
template args from other function args. */
@@ -14376,7 +14620,10 @@ type_unification_real (tree tparms,
flags))
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))
@@ -14392,15 +14639,15 @@ type_unification_real (tree tparms,
function templates and at most one of a set of
overloaded functions provides a unique match. */
if (resolve_overloaded_unification
- (tparms, targs, parm, arg, strict, sub_strict))
+ (tparms, targs, parm, arg, strict, sub_strict, explain_p))
continue;
- return 1;
+ return unify_overload_resolution_failure (explain_p, arg);
}
arg_expr = arg;
arg = unlowered_expr_type (arg);
if (arg == error_mark_node)
- return 1;
+ return unify_invalid (explain_p);
}
{
@@ -14412,7 +14659,9 @@ type_unification_real (tree tparms,
if (arg == init_list_type_node && 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;
}
}
@@ -14434,7 +14683,7 @@ type_unification_real (tree tparms,
/* Copy the parameter into parmvec. */
TREE_VEC_ELT (parmvec, 0) = TREE_VALUE (parms);
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;
/* Advance to the end of the list of parameters. */
@@ -14444,11 +14693,20 @@ type_unification_real (tree tparms,
/* Fail if we've reached the end of the parm list, and more args
are present, and the parm list isn't variadic. */
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. */
if (parms && parms != void_list_node
&& 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)
{
@@ -14503,7 +14761,10 @@ type_unification_real (tree tparms,
tree parm = TREE_VALUE (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 = 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);
if (arg == error_mark_node)
return 1;
@@ -14540,7 +14801,7 @@ type_unification_real (tree tparms,
continue;
}
- return 2;
+ return unify_parameter_deduction_failure (explain_p, tparm);
}
}
#ifdef ENABLE_CHECKING
@@ -14548,7 +14809,7 @@ type_unification_real (tree tparms,
SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs, TREE_VEC_LENGTH (targs));
#endif
- return 0;
+ return unify_success (explain_p);
}
/* Subroutine of type_unification_real. Args are like the variables
@@ -14563,7 +14824,8 @@ resolve_overloaded_unification (tree tparms,
tree parm,
tree arg,
unification_kind_t strict,
- int sub_strict)
+ int sub_strict,
+ bool explain_p)
{
tree tempargs = copy_node (targs);
int good = 0;
@@ -14615,7 +14877,7 @@ resolve_overloaded_unification (tree tparms,
{
elem = tsubst (TREE_TYPE (fn), subargs, tf_none, NULL_TREE);
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 = elem;
@@ -14643,7 +14905,7 @@ resolve_overloaded_unification (tree tparms,
for (; arg; arg = OVL_NEXT (arg))
if (try_one_overload (tparms, targs, tempargs, parm,
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 = OVL_CURRENT (arg);
@@ -14790,7 +15052,8 @@ try_one_overload (tree tparms,
tree arg,
unification_kind_t strict,
int sub_strict,
- bool addr_p)
+ bool addr_p,
+ bool explain_p)
{
int nargs;
tree tempargs;
@@ -14820,7 +15083,7 @@ try_one_overload (tree tparms,
nargs = TREE_VEC_LENGTH (targs);
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;
/* First make sure we didn't deduce anything that conflicts with
@@ -14858,7 +15121,8 @@ try_one_overload (tree tparms,
TARGS are as for unify. */
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;
@@ -14901,7 +15165,7 @@ try_class_unification (tree tparms, tree targs, tree parm, tree arg)
/* If unification failed, we're done. */
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 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
by unify. */
-static tree
-get_template_base (tree tparms, tree targs, tree parm, tree arg)
+static enum template_base_result
+get_template_base (tree tparms, tree targs, tree parm, tree arg,
+ bool explain_p, tree *result)
{
tree rval = NULL_TREE;
tree binfo;
@@ -14924,14 +15189,18 @@ get_template_base (tree tparms, tree targs, tree parm, tree arg)
binfo = TYPE_BINFO (complete_type (arg));
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
important, and this avoids multiple walks of virtual bases. */
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)
{
@@ -14944,13 +15213,17 @@ get_template_base (tree tparms, tree targs, tree parm, tree arg)
applies. */
if (rval && !same_type_p (r, rval))
- return NULL_TREE;
+ {
+ *result = NULL_TREE;
+ return tbr_ambiguous_baseclass;
+ }
rval = r;
}
}
- return rval;
+ *result = rval;
+ return tbr_success;
}
/* 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)
}
}
+#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
expansion at the end of PACKED_PARMS. Returns 0 if the type
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)
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
type_unification_real. */
-int
+static int
unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
tree packed_args, int strict, bool call_args_p,
- bool subr)
+ bool subr, bool explain_p)
{
tree parm
= 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,
if (resolve_overloaded_unification
(tparms, targs, parm, arg,
(unification_kind_t) strict,
- sub_strict)
+ sub_strict, explain_p)
!= 0)
return 1;
skip_arg_p = true;
@@ -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. */
if (arg_expr && BRACE_ENCLOSED_INITIALIZER_P (arg_expr))
arg = arg_expr;
- if (unify (tparms, targs, parm, arg, arg_strict))
- return 1;
+ RECUR_AND_CHECK_FAILURE (tparms, targs, parm, arg, arg_strict,
+ explain_p);
}
}
@@ -15252,13 +15531,21 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
ARGUMENT_PACK_INCOMPLETE_P (old_pack) = 1;
ARGUMENT_PACK_EXPLICIT_ARGS (old_pack) = explicit_args;
}
- else if (!comp_template_args (ARGUMENT_PACK_ARGS (old_pack),
- new_args))
- /* Inconsistent unification of this parameter pack. */
- return 1;
+ else
+ {
+ tree bad_old_arg, bad_new_arg;
+ 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)
@@ -15303,7 +15590,8 @@ unify_pack_expansion (tree tparms, tree targs, tree packed_parms,
qualified at this point. */
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;
tree targ;
@@ -15318,19 +15606,19 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
parm = TREE_OPERAND (parm, 0);
if (arg == error_mark_node)
- return 1;
+ return unify_invalid (explain_p);
if (arg == unknown_type_node
|| arg == init_list_type_node)
/* We can't deduce anything from this, but we might get all the
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,
even if ARG == PARM, since we won't record unifications for the
template parameters. We might need them if we're trying to
figure out which of two things is more specialized. */
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
we're dealing with a type. */
@@ -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
parameter is std::initializer_list; otherwise this is a
non-deduced context. */
- return 0;
+ return unify_success (explain_p);
elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (parm), 0);
@@ -15358,7 +15646,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
int elt_strict = strict;
if (elt == error_mark_node)
- return 1;
+ return unify_invalid (explain_p);
if (!BRACE_ENCLOSED_INITIALIZER_P (elt))
{
@@ -15370,8 +15658,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
elt = type;
}
- if (unify (tparms, targs, elttype, elt, elt_strict))
- return 1;
+ RECUR_AND_CHECK_FAILURE (tparms, targs, elttype, elt, elt_strict,
+ explain_p);
}
/* 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)
targ = listify (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
@@ -15400,7 +15688,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
is more specialized, for example. */
&& TREE_CODE (arg) != TEMPLATE_TYPE_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)
&& TYPE_P (parm) && !CP_TYPE_CONST_P (parm))
@@ -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
argument values cannot be deduced for template parameters used
within the nested-name-specifier. */
- return 0;
+ return unify_success (explain_p);
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM:
tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0));
if (tparm == error_mark_node)
- return 1;
+ return unify_invalid (explain_p);
if (TEMPLATE_TYPE_LEVEL (parm)
!= template_decl_level (tparm))
/* The PARM is not one we're trying to unify. Just check
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);
targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx);
tparm = TREE_VALUE (TREE_VEC_ELT (tparms, idx));
@@ -15442,7 +15735,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
&& TREE_CODE (tparm) != TYPE_DECL)
|| (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
&& TREE_CODE (tparm) != TEMPLATE_DECL))
- return 1;
+ gcc_unreachable ();
if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
{
@@ -15450,7 +15743,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
template parameter. */
if (TREE_CODE (arg) != BOUND_TEMPLATE_TEMPLATE_PARM
&& !CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P (arg))
- return 1;
+ return unify_template_deduction_failure (explain_p, parm, arg);
{
tree parmvec = TYPE_TI_ARGS (parm);
@@ -15492,7 +15785,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
if (coerce_template_parms (parm_parms,
full_argvec,
TYPE_TI_TEMPLATE (parm),
- tf_none,
+ (explain_p
+ ? tf_warning_or_error
+ : tf_none),
/*require_all_args=*/true,
/*use_default_args=*/false)
== error_mark_node)
@@ -15515,15 +15810,15 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
parm_variadic_p = 1;
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)
{
- if (unify (tparms, targs,
- TREE_VEC_ELT (parmvec, i),
- TREE_VEC_ELT (argvec, i),
- UNIFY_ALLOW_NONE))
- return 1;
+ RECUR_AND_CHECK_FAILURE (tparms, targs,
+ TREE_VEC_ELT (parmvec, i),
+ TREE_VEC_ELT (argvec, i),
+ UNIFY_ALLOW_NONE, explain_p);
}
if (parm_variadic_p
@@ -15531,7 +15826,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
parmvec, argvec,
UNIFY_ALLOW_NONE,
/*call_args_p=*/false,
- /*subr=*/false))
+ /*subr=*/false, explain_p))
return 1;
}
arg = TYPE_TI_TEMPLATE (arg);
@@ -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. */
if (targ != NULL_TREE && template_args_equal (targ, arg))
- return 0;
+ return unify_success (explain_p);
else if (targ)
- return 1;
+ return unify_inconsistency (explain_p, parm, targ, arg);
}
else
{
@@ -15558,20 +15853,20 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
that binds `const int' to `T'. */
if (!check_cv_quals_for_unify (strict_in | UNIFY_ALLOW_LESS_CV_QUAL,
arg, parm))
- return 1;
+ return unify_cv_qual_mismatch (explain_p, parm, arg);
/* Consider the case where ARG is `const volatile int' and
PARM is `const T'. Then, T should be `volatile int'. */
arg = cp_build_qualified_type_real
(arg, cp_type_quals (arg) & ~cp_type_quals (parm), tf_none);
if (arg == error_mark_node)
- return 1;
+ return unify_invalid (explain_p);
/* Simple cases: Value already set, does match or doesn't. */
if (targ != NULL_TREE && same_type_p (targ, arg))
- return 0;
+ return unify_success (explain_p);
else if (targ)
- return 1;
+ return unify_inconsistency (explain_p, parm, targ, arg);
/* Make sure that ARG is not a variable-sized array. (Note
that were talking about variable-sized arrays (like
@@ -15581,7 +15876,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
instantiation. Besides, such types are not allowed in
ISO C++, so we can do as we please here. */
if (variably_modified_type_p (arg, NULL_TREE))
- return 1;
+ return unify_vla_arg (explain_p, arg);
/* Strip typedefs as in convert_template_argument. */
arg = canonicalize_type_argument (arg, tf_none);
@@ -15591,35 +15886,45 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
against it unless PARM is also a parameter pack. */
if ((template_parameter_pack_p (arg) || PACK_EXPANSION_P (arg))
&& !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,
then there is a problem.
METHOD_TYPE doesn't map to any real C++ type the result of
the deduction can not be of that 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;
- return 0;
+ return unify_success (explain_p);
case TEMPLATE_PARM_INDEX:
tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0));
if (tparm == error_mark_node)
- return 1;
+ return unify_invalid (explain_p);
if (TEMPLATE_PARM_LEVEL (parm)
!= template_decl_level (tparm))
- /* The PARM is not one we're trying to unify. Just check
- to see if it matches ARG. */
- return !(TREE_CODE (arg) == TREE_CODE (parm)
- && cp_tree_equal (parm, arg));
+ {
+ /* The PARM is not one we're trying to unify. Just check
+ to see if it matches 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);
targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx);
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
with a non-type template-parameter, the non-type
@@ -15646,25 +15951,25 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
else if (uses_template_parms (tparm))
/* We haven't deduced the type of this parameter yet. Try again
later. */
- return 0;
+ return unify_success (explain_p);
else
- return 1;
+ return unify_type_mismatch (explain_p, tparm, arg);
/* If ARG is a parameter pack or an expansion, we cannot unify
against it unless PARM is also a parameter pack. */
if ((template_parameter_pack_p (arg) || PACK_EXPANSION_P (arg))
&& !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;
- return 0;
+ return unify_success (explain_p);
case PTRMEM_CST:
{
/* A pointer-to-member constant can be unified only with
another constant. */
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
wrong, depending on the strict flags) to unify also
@@ -15677,13 +15982,13 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
Unification of &A::x and &B::x must succeed. */
return unify (tparms, targs, PTRMEM_CST_MEMBER (parm),
- PTRMEM_CST_MEMBER (arg), strict);
+ PTRMEM_CST_MEMBER (arg), strict, explain_p);
}
case POINTER_TYPE:
{
if (TREE_CODE (arg) != POINTER_TYPE)
- return 1;
+ return unify_type_mismatch (explain_p, parm, arg);
/* [temp.deduct.call]
@@ -15701,21 +16006,21 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
strict |= (strict_in & UNIFY_ALLOW_DERIVED);
return unify (tparms, targs, TREE_TYPE (parm),
- TREE_TYPE (arg), strict);
+ TREE_TYPE (arg), strict, explain_p);
}
case 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),
- strict & UNIFY_ALLOW_MORE_CV_QUAL);
+ strict & UNIFY_ALLOW_MORE_CV_QUAL, explain_p);
case ARRAY_TYPE:
if (TREE_CODE (arg) != ARRAY_TYPE)
- return 1;
+ return unify_type_mismatch (explain_p, parm, arg);
if ((TYPE_DOMAIN (parm) == NULL_TREE)
!= (TYPE_DOMAIN (arg) == NULL_TREE))
- return 1;
+ return unify_type_mismatch (explain_p, parm, arg);
if (TYPE_DOMAIN (parm) != NULL_TREE)
{
tree parm_max;
@@ -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
may be a SAVE_EXPR, etc. */
if (TREE_CODE (arg_max) != MINUS_EXPR)
- return 1;
+ return unify_vla_arg (explain_p, arg);
arg_max = TREE_OPERAND (arg_max, 0);
}
@@ -15771,11 +16076,11 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
arg_max,
integer_one_node);
- if (unify (tparms, targs, parm_max, arg_max, UNIFY_ALLOW_INTEGER))
- return 1;
+ RECUR_AND_CHECK_FAILURE (tparms, targs, parm_max, arg_max,
+ UNIFY_ALLOW_INTEGER, explain_p);
}
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 COMPLEX_TYPE:
@@ -15785,16 +16090,16 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
case ENUMERAL_TYPE:
case VOID_TYPE:
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
function. */
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
will invalidate it if necessary. */
- return 0;
+ return unify_success (explain_p);
/* Types INTEGER_CST and MINUS_EXPR can come from array bounds. */
/* 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)
arg = TREE_OPERAND (arg, 0);
if (TREE_CODE (arg) != INTEGER_CST)
- return 1;
- return !tree_int_cst_equal (parm, arg);
+ return unify_template_argument_mismatch (explain_p, parm, arg);
+ return (tree_int_cst_equal (parm, arg)
+ ? unify_success (explain_p)
+ : unify_template_argument_mismatch (explain_p, parm, arg));
case TREE_VEC:
{
int i;
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))
- return 1;
+ return unify_arity (explain_p, TREE_VEC_LENGTH (arg),
+ TREE_VEC_LENGTH (parm));
for (i = 0; i < TREE_VEC_LENGTH (parm); ++i)
- if (unify (tparms, targs,
- TREE_VEC_ELT (parm, i), TREE_VEC_ELT (arg, i),
- UNIFY_ALLOW_NONE))
- return 1;
- return 0;
+ RECUR_AND_CHECK_FAILURE (tparms, targs,
+ TREE_VEC_ELT (parm, i),
+ TREE_VEC_ELT (arg, i),
+ UNIFY_ALLOW_NONE, explain_p);
+ return unify_success (explain_p);
}
case RECORD_TYPE:
case UNION_TYPE:
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 (arg))
- return 1;
+ return unify_type_mismatch (explain_p, parm, arg);
return unify (tparms, targs,
TYPE_PTRMEMFUNC_FN_TYPE (parm),
TYPE_PTRMEMFUNC_FN_TYPE (arg),
- strict);
+ strict, explain_p);
}
if (CLASSTYPE_TEMPLATE_INFO (parm))
@@ -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. */
t = try_class_unification (tparms, targs,
- parm, arg);
+ parm, arg, explain_p);
if (!t)
{
@@ -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
pointer to a derived class pointed to by the
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)
- return 1;
+ return unify_no_common_base (explain_p, r, parm, arg);
}
}
else if (CLASSTYPE_TEMPLATE_INFO (arg)
@@ -15872,14 +16182,14 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
t = arg;
else
/* 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),
- 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))
- return 1;
- return 0;
+ return unify_type_mismatch (explain_p, parm, arg);
+ return unify_success (explain_p);
case METHOD_TYPE:
case FUNCTION_TYPE:
@@ -15890,7 +16200,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
unsigned int i;
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
match exactly. We need to check them explicitly here,
@@ -15901,11 +16211,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
(UNIFY_ALLOW_NONE,
class_of_this_parm (arg),
class_of_this_parm (parm))))
- return 1;
+ return unify_cv_qual_mismatch (explain_p, parm, arg);
- if (unify (tparms, targs, TREE_TYPE (parm),
- TREE_TYPE (arg), UNIFY_ALLOW_NONE))
- return 1;
+ RECUR_AND_CHECK_FAILURE (tparms, targs, TREE_TYPE (parm),
+ TREE_TYPE (arg), UNIFY_ALLOW_NONE, explain_p);
nargs = list_length (TYPE_ARG_TYPES (arg));
args = XALLOCAVEC (tree, nargs);
@@ -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),
args, nargs, 1, DEDUCE_EXACT,
- LOOKUP_NORMAL);
+ LOOKUP_NORMAL, explain_p);
}
case OFFSET_TYPE:
@@ -15930,11 +16239,11 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
/* Check top-level cv qualifiers */
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),
- TYPE_PTRMEMFUNC_OBJECT_TYPE (arg), UNIFY_ALLOW_NONE))
- return 1;
+ RECUR_AND_CHECK_FAILURE (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
+ TYPE_PTRMEMFUNC_OBJECT_TYPE (arg),
+ UNIFY_ALLOW_NONE, explain_p);
/* Determine the type of the function we are unifying against. */
method_type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (arg));
@@ -15946,28 +16255,28 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
implicit object parameter and place them on the function
type to be restored later. */
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)
- return 1;
- if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
- TYPE_OFFSET_BASETYPE (arg), UNIFY_ALLOW_NONE))
- return 1;
+ return unify_type_mismatch (explain_p, parm, arg);
+ RECUR_AND_CHECK_FAILURE (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
+ TYPE_OFFSET_BASETYPE (arg),
+ UNIFY_ALLOW_NONE, explain_p);
return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
- strict);
+ strict, explain_p);
case CONST_DECL:
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))
- return 1;
- return 0;
+ return unify_template_argument_mismatch (explain_p, parm, arg);
+ return unify_success (explain_p);
case FIELD_DECL:
case TEMPLATE_DECL:
/* Matched cases are handled by the ARG == PARM test above. */
- return 1;
+ return unify_template_argument_mismatch (explain_p, parm, arg);
case VAR_DECL:
/* 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)
/* Since there is something following the pack
expansion, we cannot unify this template argument
list. */
- return 0;
+ return unify_success (explain_p);
}
}
@@ -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
too many arguments for a parameter list that doesn't end in
a pack expression, we can't unify. */
- if (argslen < (len - parm_variadic_p)
- || (argslen > len && !parm_variadic_p))
- return 1;
+ if (argslen < (len - parm_variadic_p))
+ return unify_too_few_arguments (explain_p, argslen, len);
+ if (argslen > len && !parm_variadic_p)
+ return unify_too_many_arguments (explain_p, argslen, len);
/* Unify all of the parameters that precede the (optional)
pack expression. */
for (i = 0; i < len - parm_variadic_p; ++i)
{
- if (unify (tparms, targs, TREE_VEC_ELT (packed_parms, i),
- TREE_VEC_ELT (packed_args, i), strict))
- return 1;
+ RECUR_AND_CHECK_FAILURE (tparms, targs,
+ TREE_VEC_ELT (packed_parms, i),
+ TREE_VEC_ELT (packed_args, i),
+ strict, explain_p);
}
if (parm_variadic_p)
return unify_pack_expansion (tparms, targs,
packed_parms, packed_args,
strict, /*call_args_p=*/false,
- /*subr=*/false);
- return 0;
+ /*subr=*/false, explain_p);
+ return unify_success (explain_p);
}
break;
@@ -16034,16 +16345,16 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
case UNDERLYING_TYPE:
/* Cannot deduce anything from TYPEOF_TYPE, DECLTYPE_TYPE,
or UNDERLYING_TYPE nodes. */
- return 0;
+ return unify_success (explain_p);
case ERROR_MARK:
/* Unification fails if we hit an error node. */
- return 1;
+ return unify_invalid (explain_p);
default:
/* An unresolved overload is a nondeduced context. */
if (type_unknown_p (parm))
- return 0;
+ return unify_success (explain_p);
gcc_assert (EXPR_P (parm));
/* 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)
if (!uses_template_parms (parm)
&& !template_args_equal (parm, arg))
- return 1;
+ return unify_expression_unequal (explain_p, parm, arg);
else
- return 0;
+ return unify_success (explain_p);
}
}
+#undef RECUR_AND_CHECK_FAILURE
/* Note that DECL can be defined in this translation unit, if
required. */
@@ -16334,10 +16646,11 @@ more_specialized_fn (tree pat1, tree pat2, int len)
for (i = 0; i < len2; i++, ta = TREE_CHAIN (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,
/*call_args_p=*/false,
- /*subr=*/0);
+ /*subr=*/0, /*explain_p=*/false)
+ == 0);
/* We cannot deduce in the other direction, because ARG1 is
a pack expansion but ARG2 is not. */
@@ -16358,10 +16671,11 @@ more_specialized_fn (tree pat1, tree pat2, int len)
for (i = 0; i < len1; i++, ta = TREE_CHAIN (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,
/*call_args_p=*/false,
- /*subr=*/0);
+ /*subr=*/0, /*explain_p=*/false)
+ == 0);
/* We cannot deduce in the other direction, because ARG2 is
a pack expansion but ARG1 is not.*/
@@ -16372,8 +16686,12 @@ more_specialized_fn (tree pat1, tree pat2, int len)
{
/* The normal case, where neither argument is a pack
expansion. */
- deduce1 = !unify (tparms1, targs1, arg1, arg2, UNIFY_ALLOW_NONE);
- deduce2 = !unify (tparms2, targs2, arg2, arg1, UNIFY_ALLOW_NONE);
+ deduce1 = (unify (tparms1, targs1, arg1, arg2,
+ 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
@@ -16587,7 +16905,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
args, ix,
(check_rettype || DECL_CONV_FN_P (fn)
? TREE_TYPE (decl_type) : NULL_TREE),
- DEDUCE_EXACT, LOOKUP_NORMAL))
+ DEDUCE_EXACT, LOOKUP_NORMAL, /*explain_p=*/false))
return NULL_TREE;
return targs;
@@ -16629,7 +16947,7 @@ get_class_bindings (tree tparms, tree spec_args, tree args)
if (unify (tparms, deduced_args,
INNERMOST_TEMPLATE_ARGS (spec_args),
INNERMOST_TEMPLATE_ARGS (args),
- UNIFY_ALLOW_NONE))
+ UNIFY_ALLOW_NONE, /*explain_p=*/false))
return NULL_TREE;
for (i = 0; i < ntparms; ++i)
@@ -19436,7 +19754,8 @@ do_auto_deduction (tree type, tree init, tree auto_node)
TREE_VEC_ELT (tparms, 0)
= build_tree_list (NULL_TREE, TYPE_NAME (auto_node));
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 (processing_template_decl)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 258128b..1c00214 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,61 @@
+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>
* gfortran.dg/coarray_14.f90: Remove dg-error "sorry not implemented".
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype29.C b/gcc/testsuite/g++.dg/cpp0x/decltype29.C
index 2bb79d0..70fe441 100644
--- a/gcc/testsuite/g++.dg/cpp0x/decltype29.C
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype29.C
@@ -13,7 +13,7 @@ decltype (ft<F> (F()))
ft() {} // { dg-error "depth" }
int main() {
- ft<struct a*, 0>(); // { dg-error "no match" }
+ ft<struct a*, 0>(); // { dg-error "no match|wrong number" }
}
// { dg-prune-output "note" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/error4.C b/gcc/testsuite/g++.dg/cpp0x/error4.C
index 29a1cdd..064c2f2f 100644
--- a/gcc/testsuite/g++.dg/cpp0x/error4.C
+++ b/gcc/testsuite/g++.dg/cpp0x/error4.C
@@ -10,7 +10,7 @@ struct S {
static U get(const volatile T&);
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" }
};
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice2.C
index 352137a..8d7d093 100644
--- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice2.C
@@ -9,8 +9,9 @@ decltype(F()) run(F f) // { dg-message "note" }
int main()
{
- auto l = []() { return 5; };
+ auto l = []() { return 5; }; // { dg-error "lambda closure type" }
run(l); // { dg-error "no match" }
// { dg-message "candidate" "candidate note" { target *-*-* } 14 }
+ // { dg-error "use of deleted function" "candidate explanation" { target *-*-* } 5 }
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/nullptr15.C b/gcc/testsuite/g++.dg/cpp0x/nullptr15.C
index e02fd55..af661ec 100644
--- a/gcc/testsuite/g++.dg/cpp0x/nullptr15.C
+++ b/gcc/testsuite/g++.dg/cpp0x/nullptr15.C
@@ -17,10 +17,10 @@ void test_g()
// Deduction to nullptr_t, no deduction to pointer type
//
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));
decltype(nullptr) mynull = 0;
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));
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr31431-2.C b/gcc/testsuite/g++.dg/cpp0x/pr31431-2.C
index 15efbc5..0764939 100644
--- a/gcc/testsuite/g++.dg/cpp0x/pr31431-2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/pr31431-2.C
@@ -4,5 +4,5 @@ template<typename, typename..., typename> void foo(); // { dg-message "note" }
void bar()
{
foo<int>(); // { dg-error "no matching function" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 6 }
+ // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 6 }
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr31431.C b/gcc/testsuite/g++.dg/cpp0x/pr31431.C
index 36f341f..afd3237 100644
--- a/gcc/testsuite/g++.dg/cpp0x/pr31431.C
+++ b/gcc/testsuite/g++.dg/cpp0x/pr31431.C
@@ -4,5 +4,5 @@ template<typename..., typename> void foo(); // { dg-message "note" }
void bar()
{
foo<int>(); // { dg-error "no matching function" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 6 }
+ // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 6 }
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr31434.C b/gcc/testsuite/g++.dg/cpp0x/pr31434.C
index 97ad079..5478616 100644
--- a/gcc/testsuite/g++.dg/cpp0x/pr31434.C
+++ b/gcc/testsuite/g++.dg/cpp0x/pr31434.C
@@ -8,5 +8,5 @@ template<typename... T> int foo(const T&) // { dg-error "not expanded with|T" }
void bar()
{
foo(0); // { dg-error "no matching" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 10 }
+ // { dg-message "(candidate|cannot convert)" "candidate note" { target *-*-* } 10 }
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae11.C b/gcc/testsuite/g++.dg/cpp0x/sfinae11.C
index 117b08b..e62c089 100644
--- a/gcc/testsuite/g++.dg/cpp0x/sfinae11.C
+++ b/gcc/testsuite/g++.dg/cpp0x/sfinae11.C
@@ -51,6 +51,6 @@ int main()
// static_assert( noexcept( f3(y) ), "shall be ill-formed(OK)." );
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" }
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae26.C b/gcc/testsuite/g++.dg/cpp0x/sfinae26.C
index 5b8cdd9..42b48eb 100644
--- a/gcc/testsuite/g++.dg/cpp0x/sfinae26.C
+++ b/gcc/testsuite/g++.dg/cpp0x/sfinae26.C
@@ -32,7 +32,7 @@ struct S {
template<class... U,
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" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/temp_default2.C b/gcc/testsuite/g++.dg/cpp0x/temp_default2.C
index fa2bb6a..dab1650 100644
--- a/gcc/testsuite/g++.dg/cpp0x/temp_default2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/temp_default2.C
@@ -8,7 +8,7 @@ void g()
f(1, 'c'); // f<int,char>(1,'c')
f(1); // f<int,double>(1,0)
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,char>(); // f<int,char>(0,0)
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/trailing4.C b/gcc/testsuite/g++.dg/cpp0x/trailing4.C
index d67b3b6..8d4baa9 100644
--- a/gcc/testsuite/g++.dg/cpp0x/trailing4.C
+++ b/gcc/testsuite/g++.dg/cpp0x/trailing4.C
@@ -8,5 +8,5 @@ auto f(T,U) -> decltype(T() + U())
template<class T> void g(T){} // { dg-message "note" }
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 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex3.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex3.C
index bd97305..018eaa3 100644
--- a/gcc/testsuite/g++.dg/cpp0x/variadic-ex3.C
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex3.C
@@ -4,8 +4,8 @@ void g()
{
int i = f<int>(5.6);
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>); // { dg-error "no matching" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 9 }
+ // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 9 }
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex4.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex4.C
index 5bf2116..0a777c4 100644
--- a/gcc/testsuite/g++.dg/cpp0x/variadic-ex4.C
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex4.C
@@ -8,6 +8,6 @@ void g()
f<int>("aa",3.0); // Y is deduced to be char*, and
// Z is deduced to be double
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
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic105.C b/gcc/testsuite/g++.dg/cpp0x/variadic105.C
index 24d7e15..66387b2 100644
--- a/gcc/testsuite/g++.dg/cpp0x/variadic105.C
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic105.C
@@ -21,4 +21,5 @@ struct call_sum {
int main() {
// This shouldn't be an error; this is bug 35722.
reverse<call_sum>(1,2); // { dg-bogus "no match" "" { xfail *-*-* } }
+ // { dg-bogus "sorry, unimplemented" "candidate explanation" { xfail *-*-* } 6 }
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-37737-2.C b/gcc/testsuite/g++.dg/cpp0x/vt-37737-2.C
index 2ff7e5b..5514259 100644
--- a/gcc/testsuite/g++.dg/cpp0x/vt-37737-2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/vt-37737-2.C
@@ -4,7 +4,7 @@ template<class U, class... T>
void f() // { dg-message "note" }
{
f<T...>(); // { dg-error "no matching" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 6 }
+ // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 6 }
}
template<>
diff --git a/gcc/testsuite/g++.dg/ext/vla2.C b/gcc/testsuite/g++.dg/ext/vla2.C
index f6a9deb..3e83c8b 100644
--- a/gcc/testsuite/g++.dg/ext/vla2.C
+++ b/gcc/testsuite/g++.dg/ext/vla2.C
@@ -15,5 +15,5 @@ void bar(int i)
char d[i] ;
begin(d); // { dg-error "no matching function" "" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 17 }
+ // { dg-message "(candidate|valid template argument)" "candidate note" { target *-*-* } 17 }
}
diff --git a/gcc/testsuite/g++.dg/other/ptrmem10.C b/gcc/testsuite/g++.dg/other/ptrmem10.C
index bc386ed..a17df7f 100644
--- a/gcc/testsuite/g++.dg/other/ptrmem10.C
+++ b/gcc/testsuite/g++.dg/other/ptrmem10.C
@@ -13,7 +13,7 @@ template <class C>
static void
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 }
}
diff --git a/gcc/testsuite/g++.dg/other/ptrmem11.C b/gcc/testsuite/g++.dg/other/ptrmem11.C
index 119cbb0..e73164e 100644
--- a/gcc/testsuite/g++.dg/other/ptrmem11.C
+++ b/gcc/testsuite/g++.dg/other/ptrmem11.C
@@ -14,7 +14,7 @@ template <typename T>
int
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 }
}
diff --git a/gcc/testsuite/g++.dg/overload/template5.C b/gcc/testsuite/g++.dg/overload/template5.C
new file mode 100644
index 0000000..b1dc65e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/template5.C
@@ -0,0 +1,15 @@
+// { 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 }
+}
diff --git a/gcc/testsuite/g++.dg/overload/unknown1.C b/gcc/testsuite/g++.dg/overload/unknown1.C
index 935f8d4..128c434 100644
--- a/gcc/testsuite/g++.dg/overload/unknown1.C
+++ b/gcc/testsuite/g++.dg/overload/unknown1.C
@@ -6,5 +6,5 @@ template <typename T> void bar(T f); // { dg-message "note" }
void baz() {
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 }
}
diff --git a/gcc/testsuite/g++.dg/template/conv11.C b/gcc/testsuite/g++.dg/template/conv11.C
index 57d06af..f08e756 100644
--- a/gcc/testsuite/g++.dg/template/conv11.C
+++ b/gcc/testsuite/g++.dg/template/conv11.C
@@ -7,5 +7,5 @@ struct A
int main()
{
A().operator int(); // { dg-error "operator int" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 9 }
+ // { dg-message "(candidate|mismatched types)" "candidate note" { target *-*-* } 9 }
}
diff --git a/gcc/testsuite/g++.dg/template/deduce3.C b/gcc/testsuite/g++.dg/template/deduce3.C
index e8a1d4e..c5d6e00 100644
--- a/gcc/testsuite/g++.dg/template/deduce3.C
+++ b/gcc/testsuite/g++.dg/template/deduce3.C
@@ -4,8 +4,8 @@ void f(int, T (*)() = 0); // { dg-message "note" }
void g() {
typedef int A[2];
f<A>(0); // { dg-error "" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 6 }
+ // { dg-error "returning an array" "candidate explanation" { target *-*-* } 2 }
typedef void F();
f<F>(0); // { dg-error "" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 9 }
+ // { dg-error "returning a function" "candidate explanation" { target *-*-* } 2 }
}
diff --git a/gcc/testsuite/g++.dg/template/dependent-expr5.C b/gcc/testsuite/g++.dg/template/dependent-expr5.C
index 1e850cd..af0dfb9 100644
--- a/gcc/testsuite/g++.dg/template/dependent-expr5.C
+++ b/gcc/testsuite/g++.dg/template/dependent-expr5.C
@@ -40,12 +40,12 @@ struct foo {
bind (&bar::baikt);
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" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 44 }
+ // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 44 }
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);
bindn (&barf);
@@ -53,15 +53,15 @@ struct foo {
bindb (&barf);
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" }
- // { 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" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 60 }
+ // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 60 }
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);
bindn (&bark);
@@ -69,7 +69,7 @@ struct foo {
bindb (&bark);
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 {
bind (&barT::baikt);
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" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 96 }
+ // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 96 }
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);
bindn (&barf);
@@ -105,15 +105,15 @@ struct foo {
bindb (&barf);
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" }
- // { 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" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 112 }
+ // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 112 }
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);
bindn (&bark);
@@ -121,7 +121,7 @@ struct foo {
bindb (&bark);
bindb (&barT::bark); // { dg-error "ambiguous" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 123 }
+ // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 123 }
}
};
diff --git a/gcc/testsuite/g++.dg/template/error45.C b/gcc/testsuite/g++.dg/template/error45.C
index 454acc6..064554d 100644
--- a/gcc/testsuite/g++.dg/template/error45.C
+++ b/gcc/testsuite/g++.dg/template/error45.C
@@ -11,7 +11,7 @@ struct enable_if< true, T >
template < typename T >
struct enable_if< true, T >::type
-f( T x );
+f( T x ); // { dg-error "not a class type" }
void
g( void )
diff --git a/gcc/testsuite/g++.dg/template/friend.C b/gcc/testsuite/g++.dg/template/friend.C
index 44cbce9..e315a1a 100644
--- a/gcc/testsuite/g++.dg/template/friend.C
+++ b/gcc/testsuite/g++.dg/template/friend.C
@@ -26,5 +26,5 @@ int main()
{
s<int>::t y;
cout << y; // { dg-error "" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 28 }
+ // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 28 }
}
diff --git a/gcc/testsuite/g++.dg/template/incomplete2.C b/gcc/testsuite/g++.dg/template/incomplete2.C
index d86ea06..b855569 100644
--- a/gcc/testsuite/g++.dg/template/incomplete2.C
+++ b/gcc/testsuite/g++.dg/template/incomplete2.C
@@ -9,6 +9,6 @@ A a; // { dg-error "incomplete type" }
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 }
}
diff --git a/gcc/testsuite/g++.dg/template/local4.C b/gcc/testsuite/g++.dg/template/local4.C
index 9a03c9a..d842076 100644
--- a/gcc/testsuite/g++.dg/template/local4.C
+++ b/gcc/testsuite/g++.dg/template/local4.C
@@ -5,6 +5,6 @@ template <typename T> void foo() {} // { dg-message "note" }
int main () {
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 }
}
diff --git a/gcc/testsuite/g++.dg/template/local6.C b/gcc/testsuite/g++.dg/template/local6.C
index 777349a..3eb828f 100644
--- a/gcc/testsuite/g++.dg/template/local6.C
+++ b/gcc/testsuite/g++.dg/template/local6.C
@@ -5,7 +5,7 @@ template <class T> struct PCVector2 // { dg-message "note" }
PCVector2<T> operator- (const PCVector2<T> &ov) const
{
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;
diff --git a/gcc/testsuite/g++.dg/template/operator9.C b/gcc/testsuite/g++.dg/template/operator9.C
index 35be778..46eef0a 100644
--- a/gcc/testsuite/g++.dg/template/operator9.C
+++ b/gcc/testsuite/g++.dg/template/operator9.C
@@ -5,6 +5,6 @@ template<operator+> void foo(); // { dg-error "before|non-function|template" }
void bar()
{
foo(); // { dg-error "no matching function" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 7 }
+ // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 7 }
}
diff --git a/gcc/testsuite/g++.dg/template/overload12.C b/gcc/testsuite/g++.dg/template/overload12.C
new file mode 100644
index 0000000..656dcae
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/overload12.C
@@ -0,0 +1,17 @@
+// { 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 }
+}
diff --git a/gcc/testsuite/g++.dg/template/ptrmem2.C b/gcc/testsuite/g++.dg/template/ptrmem2.C
index 1919047..5f03580 100644
--- a/gcc/testsuite/g++.dg/template/ptrmem2.C
+++ b/gcc/testsuite/g++.dg/template/ptrmem2.C
@@ -7,7 +7,7 @@
struct A {};
-template <typename T> T A::* Foo (); // { dg-message "note" }
+template <typename T> T A::* Foo (); // { dg-error "reference" }
void Baz ()
{
diff --git a/gcc/testsuite/g++.dg/template/sfinae2.C b/gcc/testsuite/g++.dg/template/sfinae2.C
index e39ca6b..c9e1031 100644
--- a/gcc/testsuite/g++.dg/template/sfinae2.C
+++ b/gcc/testsuite/g++.dg/template/sfinae2.C
@@ -8,7 +8,7 @@ template<int T> struct cl {
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)
{
diff --git a/gcc/testsuite/g++.dg/template/ttp25.C b/gcc/testsuite/g++.dg/template/ttp25.C
index 861d187..46762ae 100644
--- a/gcc/testsuite/g++.dg/template/ttp25.C
+++ b/gcc/testsuite/g++.dg/template/ttp25.C
@@ -18,12 +18,12 @@ void f4(T, C<5>); // { dg-message "note" }
template<int N> struct X {};
void g() {
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);
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(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>());
}
diff --git a/gcc/testsuite/g++.dg/template/unify10.C b/gcc/testsuite/g++.dg/template/unify10.C
index 8dc434b..7f2fd53 100644
--- a/gcc/testsuite/g++.dg/template/unify10.C
+++ b/gcc/testsuite/g++.dg/template/unify10.C
@@ -26,34 +26,34 @@ void cvFunction(void (CLASS::* method)() const volatile) {} // { dg-message "not
int main() {
mFunction(&MyClass::mMethod);
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" }
- // { 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" }
- // { 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" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 35 }
+ // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 35 }
cFunction(&MyClass::cMethod);
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" }
- // { 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" }
- // { 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" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 45 }
+ // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 45 }
vFunction(&MyClass::vMethod);
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" }
- // { 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" }
- // { 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" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 55 }
+ // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 55 }
cvFunction(&MyClass::cvMethod);
return 0;
diff --git a/gcc/testsuite/g++.dg/template/unify11.C b/gcc/testsuite/g++.dg/template/unify11.C
index ed6b31c..25606dc 100644
--- a/gcc/testsuite/g++.dg/template/unify11.C
+++ b/gcc/testsuite/g++.dg/template/unify11.C
@@ -20,7 +20,7 @@ struct B
C (U t)
{
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 }
}
} c;
diff --git a/gcc/testsuite/g++.dg/template/unify6.C b/gcc/testsuite/g++.dg/template/unify6.C
index b12ecb2..551c96e 100644
--- a/gcc/testsuite/g++.dg/template/unify6.C
+++ b/gcc/testsuite/g++.dg/template/unify6.C
@@ -19,5 +19,5 @@ void Bar ()
Foo3 (&Baz);
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 }
}
diff --git a/gcc/testsuite/g++.dg/template/unify7.C b/gcc/testsuite/g++.dg/template/unify7.C
index 2bfa563..88d9fd9 100644
--- a/gcc/testsuite/g++.dg/template/unify7.C
+++ b/gcc/testsuite/g++.dg/template/unify7.C
@@ -11,5 +11,5 @@ int main()
{
Foo (f);
Baz (f); // { dg-error "no matching function" "" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 13 }
+ // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 13 }
}
diff --git a/gcc/testsuite/g++.dg/template/unify9.C b/gcc/testsuite/g++.dg/template/unify9.C
index 40f6b92..f06f83a 100644
--- a/gcc/testsuite/g++.dg/template/unify9.C
+++ b/gcc/testsuite/g++.dg/template/unify9.C
@@ -14,5 +14,5 @@ const X *x;
int main () {
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 }
}
diff --git a/gcc/testsuite/g++.dg/template/varmod1.C b/gcc/testsuite/g++.dg/template/varmod1.C
index 6ae78d9..4ba1104 100644
--- a/gcc/testsuite/g++.dg/template/varmod1.C
+++ b/gcc/testsuite/g++.dg/template/varmod1.C
@@ -7,5 +7,5 @@ void bar()
int i;
int A[i][i];
foo(A); // { dg-error "" }
- // { dg-message "candidate" "candidate note" { target *-*-* } 9 }
+ // { dg-message "(candidate|not a valid template argument)" "candidate note" { target *-*-* } 9 }
}
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C
index a22615d..e3bff80 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C
@@ -278,7 +278,7 @@ SetLD<T>::remove(const T& item)
Vix x;
for (first(x); 0 != x && this->REMOVE_CURRENT != a; next(x, a))
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>
bool
@@ -287,7 +287,7 @@ SetLD<T>::contains(const T& item) const
Vix x;
for (first(x); 0 != x; next(x)) {
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 FALSE;
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash28.C b/gcc/testsuite/g++.old-deja/g++.pt/crash28.C
index 2cfed93..81ed85a 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/crash28.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/crash28.C
@@ -11,5 +11,5 @@ void f(unsigned int n) {
int x[n];
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 }
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash60.C b/gcc/testsuite/g++.old-deja/g++.pt/crash60.C
index 1aad621..747af9b 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/crash60.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/crash60.C
@@ -7,7 +7,7 @@
template< typename SID, class SDR >
void k( SID sid, SDR* p,
void (SDR::*)
- ( typename SID::T ) ); // { dg-message "note" }
+ ( typename SID::T ) ); // { dg-error "no type named 'T'" }
struct E { };
struct S { void f( int ); };
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit41.C b/gcc/testsuite/g++.old-deja/g++.pt/explicit41.C
index 560370a..c27d131 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/explicit41.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit41.C
@@ -1,6 +1,6 @@
// { dg-do assemble }
template <int I>
-void f(int i); // { dg-message "note" }
+void f(int i); // { dg-message "void f" }
void g()
{
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit77.C b/gcc/testsuite/g++.old-deja/g++.pt/explicit77.C
index 1213a15..b97c1cd 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/explicit77.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit77.C
@@ -15,5 +15,5 @@ void g() {
f<0>(s0, s2);
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 }
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/expr2.C b/gcc/testsuite/g++.old-deja/g++.pt/expr2.C
index 0dcc65f..06d22d5 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/expr2.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/expr2.C
@@ -9,5 +9,5 @@ void foo(S<J + 2>); // { dg-message "note" }
void bar()
{
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 }
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C
index 85d3e73..8802e98 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C
@@ -13,9 +13,9 @@ public:
};
template <void (A::*)() >
-void g() {} // { dg-message "note" }
+void g() {} // { dg-message "void g" }
template <int A::*>
-void h() {} // { dg-message "note" }
+void h() {} // { dg-message "void h" }
int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/spec5.C b/gcc/testsuite/g++.old-deja/g++.pt/spec5.C
index df7112a..96e8cf9 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/spec5.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/spec5.C
@@ -14,9 +14,9 @@ template void g(int i, int j);
void h()
{
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
- // { dg-message "candidate" "candidate note" { target *-*-* } 18 }
+ // { dg-message "(candidate|deduced conflicting types)" "candidate note" { target *-*-* } 18 }
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/spec6.C b/gcc/testsuite/g++.old-deja/g++.pt/spec6.C
index fc19c3c..b8f6673 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/spec6.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/spec6.C
@@ -25,9 +25,9 @@ void h()
{
S1 s1;
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.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 }
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/unify4.C b/gcc/testsuite/g++.old-deja/g++.pt/unify4.C
index 6dd9961..9285b21 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/unify4.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/unify4.C
@@ -8,6 +8,6 @@ int
main ()
{
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;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/unify6.C b/gcc/testsuite/g++.old-deja/g++.pt/unify6.C
index 0e5c034..a6f7674 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/unify6.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/unify6.C
@@ -19,7 +19,7 @@ template<> void fn<int &>() {} // ok, specialize A
template<> void fn<void ()>() {} // ok, specialize A
// 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()
{
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/unify8.C b/gcc/testsuite/g++.old-deja/g++.pt/unify8.C
index 3209260..3a86d97 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/unify8.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/unify8.C
@@ -16,6 +16,6 @@ void Foo (float); // { dg-message "note" } candidate
void baz (int **p1)
{
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
}
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb98.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb98.C
index c562031..410a336 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb98.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb98.C
@@ -15,5 +15,5 @@
void f()
{
extent(b); // { dg-error "" } no matching function
- // { dg-message "candidate" "candidate note" { target *-*-* } 17 }
+ // { dg-message "(candidate|mismatched types)" "candidate note" { target *-*-* } 17 }
}