From 3d2f6864225cc660adfc9136c859dd26e2a40135 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Sun, 17 Jul 2011 02:34:10 +0000 Subject: [PATCH] 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 From-SVN: r176365 --- gcc/cp/ChangeLog | 57 ++ gcc/cp/call.c | 144 +++- gcc/cp/class.c | 2 +- gcc/cp/cp-tree.h | 3 +- gcc/cp/pt.c | 683 +++++++++++++----- gcc/testsuite/ChangeLog | 58 ++ gcc/testsuite/g++.dg/cpp0x/decltype29.C | 2 +- gcc/testsuite/g++.dg/cpp0x/error4.C | 2 +- .../g++.dg/cpp0x/lambda/lambda-ice2.C | 3 +- gcc/testsuite/g++.dg/cpp0x/nullptr15.C | 4 +- gcc/testsuite/g++.dg/cpp0x/pr31431-2.C | 2 +- gcc/testsuite/g++.dg/cpp0x/pr31431.C | 2 +- gcc/testsuite/g++.dg/cpp0x/pr31434.C | 2 +- gcc/testsuite/g++.dg/cpp0x/sfinae11.C | 2 +- gcc/testsuite/g++.dg/cpp0x/sfinae26.C | 2 +- gcc/testsuite/g++.dg/cpp0x/temp_default2.C | 2 +- gcc/testsuite/g++.dg/cpp0x/trailing4.C | 2 +- gcc/testsuite/g++.dg/cpp0x/variadic-ex3.C | 4 +- gcc/testsuite/g++.dg/cpp0x/variadic-ex4.C | 2 +- gcc/testsuite/g++.dg/cpp0x/variadic105.C | 1 + gcc/testsuite/g++.dg/cpp0x/vt-37737-2.C | 2 +- gcc/testsuite/g++.dg/ext/vla2.C | 2 +- gcc/testsuite/g++.dg/other/ptrmem10.C | 2 +- gcc/testsuite/g++.dg/other/ptrmem11.C | 2 +- gcc/testsuite/g++.dg/overload/template5.C | 15 + gcc/testsuite/g++.dg/overload/unknown1.C | 2 +- gcc/testsuite/g++.dg/template/conv11.C | 2 +- gcc/testsuite/g++.dg/template/deduce3.C | 4 +- .../g++.dg/template/dependent-expr5.C | 32 +- gcc/testsuite/g++.dg/template/error45.C | 2 +- gcc/testsuite/g++.dg/template/friend.C | 2 +- gcc/testsuite/g++.dg/template/incomplete2.C | 2 +- gcc/testsuite/g++.dg/template/local4.C | 2 +- gcc/testsuite/g++.dg/template/local6.C | 2 +- gcc/testsuite/g++.dg/template/operator9.C | 2 +- gcc/testsuite/g++.dg/template/overload12.C | 17 + gcc/testsuite/g++.dg/template/ptrmem2.C | 2 +- gcc/testsuite/g++.dg/template/sfinae2.C | 2 +- gcc/testsuite/g++.dg/template/ttp25.C | 6 +- gcc/testsuite/g++.dg/template/unify10.C | 24 +- gcc/testsuite/g++.dg/template/unify11.C | 2 +- gcc/testsuite/g++.dg/template/unify6.C | 2 +- gcc/testsuite/g++.dg/template/unify7.C | 2 +- gcc/testsuite/g++.dg/template/unify9.C | 2 +- gcc/testsuite/g++.dg/template/varmod1.C | 2 +- .../g++.old-deja/g++.brendan/crash56.C | 4 +- gcc/testsuite/g++.old-deja/g++.pt/crash28.C | 2 +- gcc/testsuite/g++.old-deja/g++.pt/crash60.C | 2 +- .../g++.old-deja/g++.pt/explicit41.C | 2 +- .../g++.old-deja/g++.pt/explicit77.C | 2 +- gcc/testsuite/g++.old-deja/g++.pt/expr2.C | 2 +- gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C | 4 +- gcc/testsuite/g++.old-deja/g++.pt/spec5.C | 4 +- gcc/testsuite/g++.old-deja/g++.pt/spec6.C | 4 +- gcc/testsuite/g++.old-deja/g++.pt/unify4.C | 2 +- gcc/testsuite/g++.old-deja/g++.pt/unify6.C | 2 +- gcc/testsuite/g++.old-deja/g++.pt/unify8.C | 2 +- gcc/testsuite/g++.old-deja/g++.robertl/eb98.C | 2 +- 58 files changed, 872 insertions(+), 277 deletions(-) create mode 100644 gcc/testsuite/g++.dg/overload/template5.C create mode 100644 gcc/testsuite/g++.dg/template/overload12.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bb503c3b090..4db0c7e8920 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,60 @@ +2011-07-16 Nathan Froyd + Jason Merrill + + 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 * Make-lang.in (check-g++-strict-gc): New. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 56f3408adc6..99f9cc3d25a 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 7de104d4bc7..61c1380d7b2 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 96d9fa8e22e..c5905850ca4 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 d50e214ddf2..a93f677c841 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 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 258128b513c..1c00214e929 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,61 @@ +2011-07-16 Nathan Froyd + Jason Merrill + + 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 * 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 2bb79d07e78..70fe4412dcb 100644 --- a/gcc/testsuite/g++.dg/cpp0x/decltype29.C +++ b/gcc/testsuite/g++.dg/cpp0x/decltype29.C @@ -13,7 +13,7 @@ decltype (ft (F())) ft() {} // { dg-error "depth" } int main() { - ft(); // { dg-error "no match" } + ft(); // { 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 29a1cddab16..064c2f2f620 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 - static decltype(*declval()) get(...); + static decltype(*declval()) get(...); // { dg-error "operator*" } typedef decltype(get(declval())) 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 352137aad24..8d7d093dc40 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 e02fd5592eb..af661ecc3af 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(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(g((float*)mynull)); } diff --git a/gcc/testsuite/g++.dg/cpp0x/pr31431-2.C b/gcc/testsuite/g++.dg/cpp0x/pr31431-2.C index 15efbc5d359..076493938a8 100644 --- a/gcc/testsuite/g++.dg/cpp0x/pr31431-2.C +++ b/gcc/testsuite/g++.dg/cpp0x/pr31431-2.C @@ -4,5 +4,5 @@ template void foo(); // { dg-message "note" } void bar() { foo(); // { 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 36f341f3d02..afd32371574 100644 --- a/gcc/testsuite/g++.dg/cpp0x/pr31431.C +++ b/gcc/testsuite/g++.dg/cpp0x/pr31431.C @@ -4,5 +4,5 @@ template void foo(); // { dg-message "note" } void bar() { foo(); // { 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 97ad079ab0b..54786167c35 100644 --- a/gcc/testsuite/g++.dg/cpp0x/pr31434.C +++ b/gcc/testsuite/g++.dg/cpp0x/pr31434.C @@ -8,5 +8,5 @@ template 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 117b08bb623..e62c08984e7 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 5b8cdd9f545..42b48eb5a6b 100644 --- a/gcc/testsuite/g++.dg/cpp0x/sfinae26.C +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae26.C @@ -32,7 +32,7 @@ struct S { template...>::value>::type*& = enabler > - S(U...){} // # + S(U...){} // { dg-error "no type named 'type'" } }; S 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 fa2bb6aed86..dab1650e448 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(1,'c') f(1); // f(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(); // f(0,0) f(); // f(0,0) } diff --git a/gcc/testsuite/g++.dg/cpp0x/trailing4.C b/gcc/testsuite/g++.dg/cpp0x/trailing4.C index d67b3b61151..8d4baa97e5d 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 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 bd973055d06..018eaa3ed8b 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(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(f); f(f); // { 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 5bf211696a3..0a777c4853b 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("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(); // okay } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic105.C b/gcc/testsuite/g++.dg/cpp0x/variadic105.C index 24d7e15be2f..66387b23c47 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(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 2ff7e5b0b51..5514259ec3f 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 void f() // { dg-message "note" } { f(); // { 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 f6a9debca98..3e83c8b3de9 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 bc386ed56be..a17df7fb362 100644 --- a/gcc/testsuite/g++.dg/other/ptrmem10.C +++ b/gcc/testsuite/g++.dg/other/ptrmem10.C @@ -13,7 +13,7 @@ template static void bar(C *c, void (C::*m) ()) { - foo((void *)c);// { dg-error "(not a valid template arg|pointer-to-member|no matching fun)" } + foo((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 119cbb078a2..e73164eef26 100644 --- a/gcc/testsuite/g++.dg/other/ptrmem11.C +++ b/gcc/testsuite/g++.dg/other/ptrmem11.C @@ -14,7 +14,7 @@ template int bar(int T::* p) { - return foo

(0);// { dg-error "(not a valid template arg|no matching func|pointer-to-member)" } + return foo

(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 00000000000..b1dc65ebe18 --- /dev/null +++ b/gcc/testsuite/g++.dg/overload/template5.C @@ -0,0 +1,15 @@ +// { dg-do compile } + +template +int low(T a, T b, T c) { return a + b + c; } // { dg-message "template" } + +template +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 935f8d4963d..128c4344fed 100644 --- a/gcc/testsuite/g++.dg/overload/unknown1.C +++ b/gcc/testsuite/g++.dg/overload/unknown1.C @@ -6,5 +6,5 @@ template void bar(T f); // { dg-message "note" } void baz() { bar(foo); // { dg-error "" } - // { 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 57d06af3ee7..f08e756a3ee 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 e8a1d4e2b51..c5d6e00daf7 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(0); // { dg-error "" } - // { dg-message "candidate" "candidate note" { target *-*-* } 6 } + // { dg-error "returning an array" "candidate explanation" { target *-*-* } 2 } typedef void 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 1e850cd54e5..af0dfb912a2 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 454acc63149..064554dfe71 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 44cbce938d7..e315a1a0902 100644 --- a/gcc/testsuite/g++.dg/template/friend.C +++ b/gcc/testsuite/g++.dg/template/friend.C @@ -26,5 +26,5 @@ int main() { s::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 d86ea06bcd0..b855569088f 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(); // { dg-error "no matching function" } + foo(); // { 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 9a03c9a7b98..d842076bd80 100644 --- a/gcc/testsuite/g++.dg/template/local4.C +++ b/gcc/testsuite/g++.dg/template/local4.C @@ -5,6 +5,6 @@ template void foo() {} // { dg-message "note" } int main () { struct S {}; - foo (); // { dg-error "match" } + foo (); // { 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 777349a1953..3eb828fd711 100644 --- a/gcc/testsuite/g++.dg/template/local6.C +++ b/gcc/testsuite/g++.dg/template/local6.C @@ -5,7 +5,7 @@ template struct PCVector2 // { dg-message "note" } PCVector2 operator- (const PCVector2 &ov) const { return PCVector2(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 35be778765a..46eef0a9ac7 100644 --- a/gcc/testsuite/g++.dg/template/operator9.C +++ b/gcc/testsuite/g++.dg/template/operator9.C @@ -5,6 +5,6 @@ template 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 00000000000..656dcaefeed --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload12.C @@ -0,0 +1,17 @@ +// { dg-do compile } + +struct S {int x; int y;}; +template +int foo(T a, T b) {return a + b;} // { dg-message "template" } +template +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 1919047360a..5f03580c1b2 100644 --- a/gcc/testsuite/g++.dg/template/ptrmem2.C +++ b/gcc/testsuite/g++.dg/template/ptrmem2.C @@ -7,7 +7,7 @@ struct A {}; -template T A::* Foo (); // { dg-message "note" } +template 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 e39ca6b76aa..c9e103114dd 100644 --- a/gcc/testsuite/g++.dg/template/sfinae2.C +++ b/gcc/testsuite/g++.dg/template/sfinae2.C @@ -8,7 +8,7 @@ template struct cl { const static int value = T; }; -template void fn (char (*) [cl::value] = 0 ); // { dg-message "note" } +template void fn (char (*) [cl::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 861d187d4db..46762ae21af 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 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 8dc434b7577..7f2fd534624 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 ed6b31c31c4..25606dc4af8 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 b12ecb29b21..551c96ebb9f 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 2bfa56303da..88d9fd9baa0 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 40f6b9271fc..f06f83a8d1b 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 6ae78d9003f..4ba11049b5a 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 a22615dce62..e3bff80e610 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::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 bool @@ -287,7 +287,7 @@ SetLD::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 2cfed93084d..81ed85a28ef 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 1aad62132e1..747af9b4090 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 560370a8b48..c27d1312381 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 -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 1213a1511d3..b97c1cd0223 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 0dcc65f6fac..06d22d5197a 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); // { 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 85d3e7378ca..8802e983b67 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 g() {} // { dg-message "note" } +void g() {} // { dg-message "void g" } template -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 df7112ad0d0..96e8cf91160 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 fc19c3cf535..b8f6673fa0b 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 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 6dd9961088d..9285b21c2ee 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 0e5c0349544..a6f76744d22 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() {} // ok, specialize A template<> void fn() {} // ok, specialize A // now make sure we moan when we really should -template void foo(T const *){} // { dg-message "note" } +template 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 320926092f0..3a86d977ec3 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 c5620316e9c..410a3369118 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 } } -- 2.30.2