diff options
author | Jason Merrill <jason@redhat.com> | 2011-09-12 14:05:03 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-09-12 14:05:03 -0400 |
commit | c8580138b04cb4f8167a7dd2f7240479a5d45ffa (patch) | |
tree | 3c2dfa16f342d9600137880ae0596723c88a36ac | |
parent | 940023f4baf01438669c2316bc0e25eb73c9cf19 (diff) | |
download | gcc-c8580138b04cb4f8167a7dd2f7240479a5d45ffa.zip gcc-c8580138b04cb4f8167a7dd2f7240479a5d45ffa.tar.gz gcc-c8580138b04cb4f8167a7dd2f7240479a5d45ffa.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/call.c | 27 | ||||
-rw-r--r-- | gcc/cp/pt.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 2 | ||||
-rw-r--r-- | 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 83bd780..6b6c36d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2011-09-12 Jason Merrill <jason@redhat.com> + * 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 a97e8c7..81df80e 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, @@ -654,6 +655,16 @@ explicit_conversion_rejection (tree from, tree to) } 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, tree return_type, unification_kind_t strict, @@ -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 d326c84..9a5e3dd 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 65bd354..dde09f5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2011-09-12 Jason Merrill <jason@redhat.com> + * g++.dg/cpp0x/fntmpdefarg2.C: Add more tests. + * g++.dg/cpp0x/explicit7.C: New. 2011-09-12 Jakub Jelinek <jakub@redhat.com> diff --git a/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg2.C b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg2.C index 12cc836..d94843c 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<typename T = void> operator D&(); + template<typename T = void> operator D&(); // { dg-message "template conversion" } operator long(); }; void f(long); void f(B&); -int main() { f(A()); } +struct A2 { + template<typename T = void> operator B&(); +}; + +void f2(const B&); + +int main() { + f(A()); + f2(A2()); + f2(A()); // { dg-error "" } +} |