From patchwork Fri May 27 20:22:40 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Froyd X-Patchwork-Id: 97747 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 66998B6F92 for ; Sat, 28 May 2011 06:23:37 +1000 (EST) Received: (qmail 1331 invoked by alias); 27 May 2011 20:23:35 -0000 Received: (qmail 1258 invoked by uid 22791); 27 May 2011 20:23:24 -0000 X-SWARE-Spam-Status: No, hits=1.1 required=5.0 tests=AWL, BAYES_99, TW_CP, TW_DF, TW_FN, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 27 May 2011 20:22:58 +0000 Received: (qmail 29589 invoked from network); 27 May 2011 20:22:44 -0000 Received: from unknown (HELO codesourcery.com) (froydnj@127.0.0.2) by mail.codesourcery.com with ESMTPA; 27 May 2011 20:22:44 -0000 Date: Fri, 27 May 2011 16:22:40 -0400 From: Nathan Froyd To: Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: Re: [PATCH, c++] describe reasons for function template overload resolution failure Message-ID: <20110527202237.GA851@nightcrawler> References: <20110509224933.GR23480@codesourcery.com> <4DC99B34.7070301@redhat.com> <20110516173938.GA779@nightcrawler> <4DD405D0.4090108@redhat.com> <4DD41733.2020501@codesourcery.com> <4DD42299.2000206@redhat.com> <20110525181526.GA17555@nightcrawler> <4DDE750B.6080508@redhat.com> <20110526190429.GA6119@nightcrawler> <4DDFF833.5000305@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <4DDFF833.5000305@redhat.com> User-Agent: Mutt/1.5.20 (2009-06-14) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org On Fri, May 27, 2011 at 03:14:59PM -0400, Jason Merrill wrote: > On 05/26/2011 03:04 PM, Nathan Froyd wrote: > > Thanks, this is looking pretty close. A few more issues, mostly to > do with wording of the diagnostics: Thanks for all your feedback during the development of the patch. > > converted_args > > = (coerce_template_parms (tparms, explicit_targs, NULL_TREE, tf_none, > > /*require_all_args=*/false, > > /*use_default_args=*/false)); > > if (converted_args == error_mark_node) > >- return 1; > >+ { > >+ /* Run it for diagnostics. */ > >+ if (explain_p) > >+ coerce_template_parms (tparms, explicit_targs, NULL_TREE, > >+ tf_warning_or_error, > >+ /*require_all_args=*/false, > >+ /*use_default_args=*/false); > >+ return 1; > >+ } > > Instead of calling it twice, pass different tsubst_flags depending > on explain_p. And the same for all the other places where you call > a function again with tf_warning_or_error. I knew there must have been a better way to do this. =/ I think I've addressed everything in the patch below except for: > >+ /* FIXME: Should we pass in unification information and then use that > >+ to elaborate on the error messages below? */ > > Just pass in explain_p = true, and then we shouldn't need the > "unable to deduce" message here. I tried this, but for the few examples in the testsuite where it fires, I thought the error messages were more confusing, so I left this as-is and removed the FIXME. Tested as before. -Nathan gcc/cp/ 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_parameter_mismatch): 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_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. gcc/testsuite/ PR c++/45329 PR c++/48934 * 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. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index ff3dc06..c2b6502 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -430,7 +430,10 @@ enum rejection_reason_code { rr_none, rr_arity, rr_arg_conversion, - rr_bad_arg_conversion + rr_bad_arg_conversion, + rr_template_unification, + rr_template_instantiation, + rr_invalid_copy }; struct conversion_info { @@ -458,6 +461,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; }; @@ -607,6 +628,44 @@ bad_arg_conversion_rejection (tree first_arg, int n_arg, 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_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 * @@ -2889,14 +2948,23 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, 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; + { + reason = template_unification_rejection (tmpl, explicit_targs, + targs, args_without_in_chrg, + nargs_without_in_chrg, + return_type, strict, flags); + 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]: @@ -2925,7 +2993,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) @@ -3093,6 +3164,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. @@ -3139,10 +3222,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); @@ -3150,6 +3231,29 @@ print_z_candidate (const char *msgstr, struct z_candidate *candidate) case rr_bad_arg_conversion: print_conversion_rejection (loc, &r->u.bad_conversion); break; + case rr_template_unification: + /* Re-run template unification with diagnostics. */ + 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 69627cb..3a6eb3a 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -6541,7 +6541,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 ada01fb..8b9589b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5129,7 +5129,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 ab48c8f..b6cfd2b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -109,13 +109,20 @@ 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 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); @@ -129,7 +136,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); @@ -154,7 +162,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); @@ -166,8 +175,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); @@ -5265,6 +5275,220 @@ 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_parameter_mismatch (bool explain_p, tree parm, tree tparm) +{ + if (explain_p) + inform (input_location, + " template parameter %qT does not match %qD", tparm, parm); + 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 @@ -6521,11 +6745,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; @@ -6538,11 +6764,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) { @@ -13608,7 +13849,7 @@ static GTY((param_is (spec_entry))) htab_t current_deduction_htab; 0.5% of compile time. */ static tree -deduction_tsubst_fntype (tree fn, tree targs) +deduction_tsubst_fntype (tree fn, tree targs, tsubst_flags_t complain) { unsigned i; spec_entry **slot; @@ -13678,7 +13919,7 @@ deduction_tsubst_fntype (tree fn, tree targs) VEC_safe_push (spec_entry, gc, current_deduction_vec, &elt); } - r = tsubst (fntype, targs, tf_none, NULL_TREE); + r = tsubst (fntype, targs, complain, NULL_TREE); /* After doing the substitution, make sure we didn't hit it again. Note that we might have switched to a hash table during tsubst. */ @@ -13891,7 +14132,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; @@ -13926,12 +14168,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; @@ -13991,7 +14236,10 @@ fn_type_unification (tree fn, processing_template_decl += incomplete; push_deduction_access_scope (fn); - fntype = deduction_tsubst_fntype (fn, converted_args); + fntype = deduction_tsubst_fntype (fn, converted_args, + (explain_p + ? tf_warning_or_error + : tf_none)); pop_deduction_access_scope (fn); processing_template_decl -= incomplete; @@ -14024,7 +14272,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 @@ -14050,7 +14298,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: @@ -14065,7 +14313,10 @@ fn_type_unification (tree fn, { tree substed; push_deduction_access_scope (fn); - substed = deduction_tsubst_fntype (fn, targs); + substed = deduction_tsubst_fntype (fn, targs, + (explain_p + ? tf_warning_or_error + : tf_none)); pop_deduction_access_scope (fn); if (substed == error_mark_node) return 1; @@ -14083,7 +14334,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)); } } @@ -14214,7 +14466,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; @@ -14285,7 +14538,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. */ @@ -14311,7 +14564,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)) @@ -14327,15 +14583,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); } { @@ -14347,7 +14603,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; } } @@ -14369,7 +14627,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. */ @@ -14379,11 +14637,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) { @@ -14438,7 +14705,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; @@ -14475,7 +14745,7 @@ type_unification_real (tree tparms, continue; } - return 2; + return unify_parameter_deduction_failure (explain_p, tparm); } } #ifdef ENABLE_CHECKING @@ -14483,7 +14753,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 @@ -14498,7 +14768,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; @@ -14549,7 +14820,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; @@ -14569,7 +14840,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); @@ -14715,7 +14986,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; @@ -14745,7 +15017,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 @@ -14783,7 +15055,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; @@ -14826,7 +15099,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; @@ -14839,8 +15112,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; @@ -14849,14 +15123,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) { @@ -14869,13 +15147,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. */ @@ -14957,6 +15239,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 @@ -14964,10 +15252,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); @@ -15057,7 +15345,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; @@ -15085,8 +15373,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); } } @@ -15177,13 +15465,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) @@ -15228,7 +15524,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; @@ -15243,19 +15540,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. */ @@ -15274,7 +15571,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); @@ -15283,7 +15580,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)) { @@ -15295,8 +15592,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 @@ -15308,7 +15605,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 @@ -15325,7 +15622,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)) @@ -15343,21 +15640,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)); @@ -15367,7 +15669,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) { @@ -15375,7 +15677,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); @@ -15417,7 +15719,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) @@ -15440,15 +15744,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 @@ -15456,7 +15760,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); @@ -15471,9 +15775,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 { @@ -15483,20 +15787,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 @@ -15506,7 +15810,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 = strip_typedefs (arg); @@ -15516,35 +15820,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_template_parameter_mismatch (explain_p, parm, tparm); + 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 @@ -15571,25 +15885,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 @@ -15602,13 +15916,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] @@ -15626,21 +15940,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; @@ -15679,7 +15993,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); } @@ -15696,11 +16010,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: @@ -15710,16 +16024,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. */ @@ -15728,38 +16042,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)) @@ -15770,7 +16087,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) { @@ -15783,10 +16100,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) @@ -15797,14 +16116,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: @@ -15815,7 +16134,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, @@ -15826,11 +16145,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); @@ -15842,7 +16160,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: @@ -15855,11 +16173,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)); @@ -15871,28 +16189,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 @@ -15922,7 +16240,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); } } @@ -15931,25 +16249,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; @@ -15959,16 +16279,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 @@ -15992,11 +16312,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. */ @@ -16259,10 +16580,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. */ @@ -16283,10 +16605,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.*/ @@ -16297,8 +16620,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 @@ -16512,7 +16839,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; @@ -16554,7 +16881,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) @@ -19290,7 +19617,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 (type && type != error_mark_node) diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice2.C index 352137a..120dfaa 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 *-*-* } 14 } } diff --git a/gcc/testsuite/g++.dg/cpp0x/nullptr15.C b/gcc/testsuite/g++.dg/cpp0x/nullptr15.C index e02fd55..af661ec 100644 --- a/gcc/testsuite/g++.dg/cpp0x/nullptr15.C +++ b/gcc/testsuite/g++.dg/cpp0x/nullptr15.C @@ -17,10 +17,10 @@ void test_g() // Deduction to nullptr_t, no deduction to pointer type // g(nullptr); // { dg-error "no matching function for call to " } - // { dg-message "candidate" "candidate note" { target *-*-* } 19 } + // { dg-message "(candidate|mismatched types)" "candidate note" { target *-*-* } 19 } type_equal(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 15efbc5..0764939 100644 --- a/gcc/testsuite/g++.dg/cpp0x/pr31431-2.C +++ b/gcc/testsuite/g++.dg/cpp0x/pr31431-2.C @@ -4,5 +4,5 @@ template 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 36f341f..afd3237 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 97ad079..5478616 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 a3ffc34..a525566 100644 --- a/gcc/testsuite/g++.dg/cpp0x/sfinae11.C +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae11.C @@ -50,7 +50,7 @@ int main() static_assert( noexcept( f2(y) ), "OK." ); // static_assert( noexcept( f3(y) ), "shall be ill-formed(OK)." ); - static_assert( noexcept( f1(z) ), "shall be ill-formed." ); // { dg-error "no match" } - static_assert( noexcept( f2(z) ), "shall be ill-formed." ); // { dg-error "no match" } - static_assert( !noexcept( f3(z) ), "shall be ill-formed." ); // { dg-error "no match" } + static_assert( noexcept( f1(z) ), "shall be ill-formed." ); // { dg-error "(no match|no member)" } + static_assert( noexcept( f2(z) ), "shall be ill-formed." ); // { dg-error "(no match|could not convert)" } + static_assert( !noexcept( f3(z) ), "shall be ill-formed." ); // { dg-error "(no match|no member)" } } diff --git a/gcc/testsuite/g++.dg/cpp0x/temp_default2.C b/gcc/testsuite/g++.dg/cpp0x/temp_default2.C index fa2bb6a..dab1650 100644 --- a/gcc/testsuite/g++.dg/cpp0x/temp_default2.C +++ b/gcc/testsuite/g++.dg/cpp0x/temp_default2.C @@ -8,7 +8,7 @@ void g() f(1, 'c'); // f(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 d67b3b6..8d4baa9 100644 --- a/gcc/testsuite/g++.dg/cpp0x/trailing4.C +++ b/gcc/testsuite/g++.dg/cpp0x/trailing4.C @@ -8,5 +8,5 @@ auto f(T,U) -> decltype(T() + U()) template void g(T){} // { dg-message "note" } int main() { g(f); } // { dg-error "no matching function" } -// { dg-message "candidate" "candidate note" { target *-*-* } 10 } +// { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 10 } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-ex3.C b/gcc/testsuite/g++.dg/cpp0x/variadic-ex3.C index bd97305..018eaa3 100644 --- a/gcc/testsuite/g++.dg/cpp0x/variadic-ex3.C +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex3.C @@ -4,8 +4,8 @@ void g() { int i = f(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 5bf2116..0a777c4 100644 --- a/gcc/testsuite/g++.dg/cpp0x/variadic-ex4.C +++ b/gcc/testsuite/g++.dg/cpp0x/variadic-ex4.C @@ -8,6 +8,6 @@ void g() f("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 24d7e15..2729b31 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-message "sorry, unimplemented" "candidate explanation" { target *-*-* } 23 } } diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-37737-2.C b/gcc/testsuite/g++.dg/cpp0x/vt-37737-2.C index 2ff7e5b..5514259 100644 --- a/gcc/testsuite/g++.dg/cpp0x/vt-37737-2.C +++ b/gcc/testsuite/g++.dg/cpp0x/vt-37737-2.C @@ -4,7 +4,7 @@ template 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 f6a9deb..3e83c8b 100644 --- a/gcc/testsuite/g++.dg/ext/vla2.C +++ b/gcc/testsuite/g++.dg/ext/vla2.C @@ -15,5 +15,5 @@ void bar(int i) char d[i] ; begin(d); // { dg-error "no matching function" "" } - // { dg-message "candidate" "candidate note" { target *-*-* } 17 } + // { dg-message "(candidate|valid template argument)" "candidate note" { target *-*-* } 17 } } diff --git a/gcc/testsuite/g++.dg/other/ptrmem10.C b/gcc/testsuite/g++.dg/other/ptrmem10.C index bc386ed..a17df7f 100644 --- a/gcc/testsuite/g++.dg/other/ptrmem10.C +++ b/gcc/testsuite/g++.dg/other/ptrmem10.C @@ -13,7 +13,7 @@ template 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 119cbb0..e73164e 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 0000000..b1dc65e --- /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 935f8d4..128c434 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 57d06af..f08e756 100644 --- a/gcc/testsuite/g++.dg/template/conv11.C +++ b/gcc/testsuite/g++.dg/template/conv11.C @@ -7,5 +7,5 @@ struct A int main() { A().operator int(); // { dg-error "operator int" } - // { dg-message "candidate" "candidate note" { target *-*-* } 9 } + // { dg-message "(candidate|mismatched types)" "candidate note" { target *-*-* } 9 } } diff --git a/gcc/testsuite/g++.dg/template/dependent-expr5.C b/gcc/testsuite/g++.dg/template/dependent-expr5.C index 1e850cd..af0dfb9 100644 --- a/gcc/testsuite/g++.dg/template/dependent-expr5.C +++ b/gcc/testsuite/g++.dg/template/dependent-expr5.C @@ -40,12 +40,12 @@ struct foo { bind (&bar::baikt); bind (&barf); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 42 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 42 } bind (&foo::barf); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 44 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 44 } bindm (&barf); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 47 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 47 } bindm (&foo::barf); bindn (&barf); @@ -53,15 +53,15 @@ struct foo { bindb (&barf); bindb (&foo::barf); // { dg-error "ambiguous" } - // { dg-message "candidate" "candidate note" { target *-*-* } 55 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 55 } bind (&bark); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 58 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 58 } bind (&bar::bark); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 60 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 60 } bindm (&bark); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 63 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 63 } bindm (&bar::bark); bindn (&bark); @@ -69,7 +69,7 @@ struct foo { bindb (&bark); bindb (&bar::bark); // { dg-error "ambiguous" } - // { dg-message "candidate" "candidate note" { target *-*-* } 71 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 71 } } }; @@ -92,12 +92,12 @@ struct foo { bind (&barT::baikt); bind (&barf); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 94 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 94 } bind (&foo::barf); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 96 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 96 } bindm (&barf); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 99 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 99 } bindm (&foo::barf); bindn (&barf); @@ -105,15 +105,15 @@ struct foo { bindb (&barf); bindb (&foo::barf); // { dg-error "ambiguous" } - // { dg-message "candidate" "candidate note" { target *-*-* } 107 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 107 } bind (&bark); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 110 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 110 } bind (&barT::bark); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 112 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 112 } bindm (&bark); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 115 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 115 } bindm (&barT::bark); bindn (&bark); @@ -121,7 +121,7 @@ struct foo { bindb (&bark); bindb (&barT::bark); // { dg-error "ambiguous" } - // { dg-message "candidate" "candidate note" { target *-*-* } 123 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 123 } } }; diff --git a/gcc/testsuite/g++.dg/template/friend.C b/gcc/testsuite/g++.dg/template/friend.C index 44cbce9..e315a1a 100644 --- a/gcc/testsuite/g++.dg/template/friend.C +++ b/gcc/testsuite/g++.dg/template/friend.C @@ -26,5 +26,5 @@ int main() { s::t y; cout << y; // { dg-error "" } - // { dg-message "candidate" "candidate note" { target *-*-* } 28 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 28 } } diff --git a/gcc/testsuite/g++.dg/template/incomplete2.C b/gcc/testsuite/g++.dg/template/incomplete2.C index d86ea06..b855569 100644 --- a/gcc/testsuite/g++.dg/template/incomplete2.C +++ b/gcc/testsuite/g++.dg/template/incomplete2.C @@ -9,6 +9,6 @@ A a; // { dg-error "incomplete type" } void bar() { - foo(); // { 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 9a03c9a..d842076 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 4a87177..972da84 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 35be778..46eef0a 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 0000000..656dcae --- /dev/null +++ b/gcc/testsuite/g++.dg/template/overload12.C @@ -0,0 +1,17 @@ +// { dg-do compile } + +struct S {int x; int y;}; +template +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/ttp25.C b/gcc/testsuite/g++.dg/template/ttp25.C index 861d187..46762ae 100644 --- a/gcc/testsuite/g++.dg/template/ttp25.C +++ b/gcc/testsuite/g++.dg/template/ttp25.C @@ -18,12 +18,12 @@ void f4(T, C<5>); // { dg-message "note" } template struct X {}; void g() { f1(5l, X<5>()); // { dg-error "no matching" } - // { dg-message "candidate" "candidate note" { target *-*-* } 20 } + // { dg-message "(candidate|inconsistent with)" "candidate note" { target *-*-* } 20 } f2(X<5>(), 5); f3(X<5>(), 5l); // { dg-error "no matching" } - // { dg-message "candidate" "candidate note" { target *-*-* } 23 } + // { dg-message "(candidate|inconsistent with)" "candidate note" { target *-*-* } 23 } f4(5, X<5>()); f4(5l, X<5>()); // { dg-error "no matching" } - // { dg-message "candidate" "candidate note" { target *-*-* } 26 } + // { dg-message "(candidate|inconsistent with)" "candidate note" { target *-*-* } 26 } f4((short)5, X<5>()); } diff --git a/gcc/testsuite/g++.dg/template/unify10.C b/gcc/testsuite/g++.dg/template/unify10.C index 8dc434b..7f2fd53 100644 --- a/gcc/testsuite/g++.dg/template/unify10.C +++ b/gcc/testsuite/g++.dg/template/unify10.C @@ -26,34 +26,34 @@ void cvFunction(void (CLASS::* method)() const volatile) {} // { dg-message "not int main() { mFunction(&MyClass::mMethod); mFunction(&MyClass::cMethod); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 28 } + // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 28 } mFunction(&MyClass::vMethod); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 30 } + // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 30 } mFunction(&MyClass::cvMethod); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 32 } + // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 32 } cFunction(&MyClass::mMethod); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 35 } + // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 35 } cFunction(&MyClass::cMethod); cFunction(&MyClass::vMethod); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 38 } + // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 38 } cFunction(&MyClass::cvMethod); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 40 } + // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 40 } vFunction(&MyClass::mMethod); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 43 } + // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 43 } vFunction(&MyClass::cMethod); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 45 } + // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 45 } vFunction(&MyClass::vMethod); vFunction(&MyClass::cvMethod); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 48 } + // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 48 } cvFunction(&MyClass::mMethod); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 51 } + // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 51 } cvFunction(&MyClass::cMethod); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 53 } + // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 53 } cvFunction(&MyClass::vMethod); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 55 } + // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 55 } cvFunction(&MyClass::cvMethod); return 0; diff --git a/gcc/testsuite/g++.dg/template/unify11.C b/gcc/testsuite/g++.dg/template/unify11.C index ed6b31c..25606dc 100644 --- a/gcc/testsuite/g++.dg/template/unify11.C +++ b/gcc/testsuite/g++.dg/template/unify11.C @@ -20,7 +20,7 @@ struct B C (U t) { A a; - A b = foo (this, a, t); // { dg-error "no matching function" } + A b = foo (this, a, t); // { dg-error "(no matching function|is not a)" } // { dg-message "candidate" "candidate note" { target *-*-* } 23 } } } c; diff --git a/gcc/testsuite/g++.dg/template/unify6.C b/gcc/testsuite/g++.dg/template/unify6.C index b12ecb2..551c96e 100644 --- a/gcc/testsuite/g++.dg/template/unify6.C +++ b/gcc/testsuite/g++.dg/template/unify6.C @@ -19,5 +19,5 @@ void Bar () Foo3 (&Baz); Foo3 (&Baz, &Baz); // { dg-error "no matching function" "" } - // { dg-message "candidate" "candidate note" { target *-*-* } 21 } + // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 21 } } diff --git a/gcc/testsuite/g++.dg/template/unify7.C b/gcc/testsuite/g++.dg/template/unify7.C index 2bfa563..88d9fd9 100644 --- a/gcc/testsuite/g++.dg/template/unify7.C +++ b/gcc/testsuite/g++.dg/template/unify7.C @@ -11,5 +11,5 @@ int main() { Foo (f); Baz (f); // { dg-error "no matching function" "" } - // { dg-message "candidate" "candidate note" { target *-*-* } 13 } + // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 13 } } diff --git a/gcc/testsuite/g++.dg/template/unify9.C b/gcc/testsuite/g++.dg/template/unify9.C index 40f6b92..f06f83a 100644 --- a/gcc/testsuite/g++.dg/template/unify9.C +++ b/gcc/testsuite/g++.dg/template/unify9.C @@ -14,5 +14,5 @@ const X *x; int main () { f (*x, &X::g); // { dg-error "no matching function" } - // { dg-message "candidate" "candidate note" { target *-*-* } 16 } + // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 16 } } diff --git a/gcc/testsuite/g++.dg/template/varmod1.C b/gcc/testsuite/g++.dg/template/varmod1.C index 6ae78d9..4ba1104 100644 --- a/gcc/testsuite/g++.dg/template/varmod1.C +++ b/gcc/testsuite/g++.dg/template/varmod1.C @@ -7,5 +7,5 @@ void bar() int i; int A[i][i]; foo(A); // { dg-error "" } - // { dg-message "candidate" "candidate note" { target *-*-* } 9 } + // { dg-message "(candidate|not a valid template argument)" "candidate note" { target *-*-* } 9 } } diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C index a22615d..e3bff80 100644 --- a/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C +++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash56.C @@ -278,7 +278,7 @@ SetLD::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 2cfed93..81ed85a 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/crash28.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/crash28.C @@ -11,5 +11,5 @@ void f(unsigned int n) { int x[n]; asize(x); // { dg-error "" } no matching function - // { dg-message "candidate" "candidate note" { target *-*-* } 13 } + // { dg-message "(candidate|not a valid template argument)" "candidate note" { target *-*-* } 13 } } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit41.C b/gcc/testsuite/g++.old-deja/g++.pt/explicit41.C index 560370a..c27d131 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/explicit41.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit41.C @@ -1,6 +1,6 @@ // { dg-do assemble } template -void f(int i); // { dg-message "note" } +void f(int i); // { dg-message "void f" } void g() { diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit77.C b/gcc/testsuite/g++.old-deja/g++.pt/explicit77.C index 1213a15..b97c1cd 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/explicit77.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit77.C @@ -15,5 +15,5 @@ void g() { f<0>(s0, s2); f(s0, s2); // { dg-error "" } no matching function - // { dg-message "candidate" "candidate note" { target *-*-* } 17 } + // { dg-message "(candidate|deduced conflicting types|ambiguous base class)" "candidate note" { target *-*-* } 17 } } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/expr2.C b/gcc/testsuite/g++.old-deja/g++.pt/expr2.C index 0dcc65f..06d22d5 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/expr2.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/expr2.C @@ -9,5 +9,5 @@ void foo(S); // { dg-message "note" } void bar() { foo(S<3>()); // { dg-error "" } no way to deduce J from this. - // { dg-message "candidate" "candidate note" { target *-*-* } 11 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 11 } } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C index 85d3e73..8802e98 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem6.C @@ -13,9 +13,9 @@ public: }; template -void 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 df7112a..96e8cf9 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/spec5.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/spec5.C @@ -14,9 +14,9 @@ template void g(int i, int j); void h() { f(3, 'c'); // { dg-error "" } no matching function - // { dg-message "candidate" "candidate note" { target *-*-* } 16 } + // { dg-message "(candidate|deduced conflicting types)" "candidate note" { target *-*-* } 16 } g(3, 'c'); // { dg-error "" } no matching function - // { dg-message "candidate" "candidate note" { target *-*-* } 18 } + // { dg-message "(candidate|deduced conflicting types)" "candidate note" { target *-*-* } 18 } } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/spec6.C b/gcc/testsuite/g++.old-deja/g++.pt/spec6.C index fc19c3c..b8f6673 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/spec6.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/spec6.C @@ -25,9 +25,9 @@ void h() { S1 s1; s1.f(3, 'c'); // { dg-error "" } no matching function - // { dg-message "candidate" "candidate note" { target *-*-* } 27 } + // { dg-message "(candidate|deduced conflicting types)" "candidate note" { target *-*-* } 27 } S2 s2; s2.f(3, 'c'); // { dg-error "" } no matching function - // { dg-message "candidate" "candidate note" { target *-*-* } 31 } + // { dg-message "(candidate|deduced conflicting types)" "candidate note" { target *-*-* } 31 } } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/unify4.C b/gcc/testsuite/g++.old-deja/g++.pt/unify4.C index 6dd9961..9285b21 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/unify4.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/unify4.C @@ -8,6 +8,6 @@ int main () { f (g); // { dg-error "" } ambiguous unification - // { dg-message "candidate" "candidate note" { target *-*-* } 10 } + // { dg-message "(candidate|deduce template parameter)" "candidate note" { target *-*-* } 10 } return 0; } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/unify8.C b/gcc/testsuite/g++.old-deja/g++.pt/unify8.C index 3209260..3a86d97 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/unify8.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/unify8.C @@ -16,6 +16,6 @@ void Foo (float); // { dg-message "note" } candidate void baz (int **p1) { Foo (p1); // { dg-error "match" } no such function - // { dg-message "candidate" "candidate note" { target *-*-* } 18 } + // { dg-message "(candidate|incompatible cv-qualifiers)" "candidate note" { target *-*-* } 18 } Bar (p1); // OK } diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb98.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb98.C index c562031..410a336 100644 --- a/gcc/testsuite/g++.old-deja/g++.robertl/eb98.C +++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb98.C @@ -15,5 +15,5 @@ void f() { extent(b); // { dg-error "" } no matching function - // { dg-message "candidate" "candidate note" { target *-*-* } 17 } + // { dg-message "(candidate|mismatched types)" "candidate note" { target *-*-* } 17 } }