From c8580138b04cb4f8167a7dd2f7240479a5d45ffa Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 12 Sep 2011 14:05:03 -0400 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 7 ++++++ gcc/cp/call.c | 27 +++++++++++++++++++++++ gcc/cp/pt.c | 16 ++++++++++---- gcc/testsuite/ChangeLog | 2 ++ gcc/testsuite/g++.dg/cpp0x/fntmpdefarg2.C | 14 ++++++++++-- 5 files changed, 60 insertions(+), 6 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 83bd7801cdc..6b6c36da4ec 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 a97e8c79417..81df80ed88e 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 d326c842c70..9a5e3ddf13b 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 65bd3546799..dde09f5773f 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 12cc83659c5..d94843c1fe5 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 "" } +} -- 2.30.2