From: Jason Merrill Date: Mon, 12 Sep 2011 18:05:03 +0000 (-0400) Subject: pt.c (type_unification_real): Fix handling of DEDUCE_CONV with no deducible template... X-Git-Tag: releases/gcc-4.7.0~3805 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c8580138b04cb4f8167a7dd2f7240479a5d45ffa;p=thirdparty%2Fgcc.git pt.c (type_unification_real): Fix handling of DEDUCE_CONV with no deducible template parameters. * pt.c (type_unification_real): Fix handling of DEDUCE_CONV with no deducible template parameters. * call.c (rejection_reason_code): Add rr_template_conversion. (print_z_candidate): Handle it. (template_conversion_rejection): New. (build_user_type_conversion_1): Use it. From-SVN: r178791 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 83bd7801cdcf..6b6c36da4ec8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2011-09-12 Jason Merrill + * pt.c (type_unification_real): Fix handling of DEDUCE_CONV + with no deducible template parameters. + * call.c (rejection_reason_code): Add rr_template_conversion. + (print_z_candidate): Handle it. + (template_conversion_rejection): New. + (build_user_type_conversion_1): Use it. + * call.c (merge_conversion_sequences): Set bad_p and user_conv_p on all of the second conversion sequence. (build_user_type_conversion_1): Set bad_p on the ck_user conv. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index a97e8c79417d..81df80ed88ec 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -432,6 +432,7 @@ enum rejection_reason_code { rr_none, rr_arity, rr_explicit_conversion, + rr_template_conversion, rr_arg_conversion, rr_bad_arg_conversion, rr_template_unification, @@ -653,6 +654,16 @@ explicit_conversion_rejection (tree from, tree to) return r; } +static struct rejection_reason * +template_conversion_rejection (tree from, tree to) +{ + struct rejection_reason *r = alloc_rejection (rr_template_conversion); + r->u.conversion.n_arg = 0; + r->u.conversion.from_type = from; + r->u.conversion.to_type = to; + return r; +} + static struct rejection_reason * template_unification_rejection (tree tmpl, tree explicit_targs, tree targs, const tree *args, unsigned int nargs, @@ -3135,6 +3146,12 @@ 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_conversion: + inform (loc, " conversion from return type %qT of template " + "conversion function specialization to %qT is not an " + "exact match", 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 @@ -3495,6 +3512,16 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) = bad_arg_conversion_rejection (NULL_TREE, -1, rettype, totype); } + else if (primary_template_instantiation_p (cand->fn) + && ics->rank > cr_exact) + { + /* 13.3.3.1.2: If the user-defined conversion is specified by + a specialization of a conversion function template, the + second standard conversion sequence shall have exact match + rank. */ + cand->viable = -1; + cand->reason = template_conversion_rejection (rettype, totype); + } } } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d326c842c701..9a5e3ddf13bb 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14709,10 +14709,18 @@ type_unification_real (tree tparms, if (same_type_p (parm, type)) continue; - if (strict != DEDUCE_EXACT - && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg, - flags)) - continue; + if (strict == DEDUCE_CONV) + { + if (can_convert_arg (type, parm, NULL_TREE, flags)) + continue; + } + else if (strict != DEDUCE_EXACT) + { + if (can_convert_arg (parm, type, + TYPE_P (arg) ? NULL_TREE : arg, + flags)) + continue; + } if (strict == DEDUCE_EXACT) return unify_type_mismatch (explain_p, parm, arg); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 65bd35467997..dde09f5773fd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2011-09-12 Jason Merrill + * g++.dg/cpp0x/fntmpdefarg2.C: Add more tests. + * g++.dg/cpp0x/explicit7.C: New. 2011-09-12 Jakub Jelinek diff --git a/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg2.C b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg2.C index 12cc83659c59..d94843c1fe56 100644 --- a/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg2.C +++ b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg2.C @@ -4,11 +4,21 @@ struct B { }; struct D : B { }; struct A { - template operator D&(); + template operator D&(); // { dg-message "template conversion" } operator long(); }; void f(long); void f(B&); -int main() { f(A()); } +struct A2 { + template operator B&(); +}; + +void f2(const B&); + +int main() { + f(A()); + f2(A2()); + f2(A()); // { dg-error "" } +}