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.
rr_none,
rr_arity,
rr_explicit_conversion,
+ rr_template_conversion,
rr_arg_conversion,
rr_bad_arg_conversion,
rr_template_unification,
}
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,
"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
= 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);
+ }
}
}
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);