Commit 53db1bc0 by Jason Merrill Committed by Jason Merrill

call.c (can_convert): Allow user-defined conversions.

	* call.c (can_convert): Allow user-defined conversions.
	(can_convert_standard): New.
	* cp-tree.h: Declare it.
	* cvt.c (convert_to_reference): Use it.
	* pt.c (convert_nontype_argument): Likewise.
	* search.c (check_final_overrider): Likewise.
	Don't worry about user-defined conversions.

From-SVN: r200937
parent e43257e8
2013-07-13 Jason Merrill <jason@redhat.com>
* call.c (can_convert): Allow user-defined conversions.
(can_convert_standard): New.
* cp-tree.h: Declare it.
* cvt.c (convert_to_reference): Use it.
* pt.c (convert_nontype_argument): Likewise.
* search.c (check_final_overrider): Likewise.
Don't worry about user-defined conversions.
2013-07-10 Paolo Carlini <paolo.carlini@oracle.com> 2013-07-10 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/57869 PR c++/57869
......
...@@ -8814,6 +8814,20 @@ tourney (struct z_candidate *candidates, tsubst_flags_t complain) ...@@ -8814,6 +8814,20 @@ tourney (struct z_candidate *candidates, tsubst_flags_t complain)
bool bool
can_convert (tree to, tree from, tsubst_flags_t complain) can_convert (tree to, tree from, tsubst_flags_t complain)
{ {
tree arg = NULL_TREE;
/* implicit_conversion only considers user-defined conversions
if it has an expression for the call argument list. */
if (CLASS_TYPE_P (from) || CLASS_TYPE_P (to))
arg = build1 (CAST_EXPR, from, NULL_TREE);
return can_convert_arg (to, from, arg, LOOKUP_IMPLICIT, complain);
}
/* Returns nonzero if things of type FROM can be converted to TO with a
standard conversion. */
bool
can_convert_standard (tree to, tree from, tsubst_flags_t complain)
{
return can_convert_arg (to, from, NULL_TREE, LOOKUP_IMPLICIT, complain); return can_convert_arg (to, from, NULL_TREE, LOOKUP_IMPLICIT, complain);
} }
......
...@@ -5007,6 +5007,7 @@ extern tree build_op_delete_call (enum tree_code, tree, tree, ...@@ -5007,6 +5007,7 @@ extern tree build_op_delete_call (enum tree_code, tree, tree,
bool, tree, tree, bool, tree, tree,
tsubst_flags_t); tsubst_flags_t);
extern bool can_convert (tree, tree, tsubst_flags_t); extern bool can_convert (tree, tree, tsubst_flags_t);
extern bool can_convert_standard (tree, tree, tsubst_flags_t);
extern bool can_convert_arg (tree, tree, tree, int, extern bool can_convert_arg (tree, tree, tree, int,
tsubst_flags_t); tsubst_flags_t);
extern bool can_convert_arg_bad (tree, tree, tree, int, extern bool can_convert_arg_bad (tree, tree, tree, int,
......
...@@ -428,7 +428,7 @@ convert_to_reference (tree reftype, tree expr, int convtype, ...@@ -428,7 +428,7 @@ convert_to_reference (tree reftype, tree expr, int convtype,
intype = TYPE_MAIN_VARIANT (intype); intype = TYPE_MAIN_VARIANT (intype);
can_convert_intype_to_type = can_convert (type, intype, complain); can_convert_intype_to_type = can_convert_standard (type, intype, complain);
if (!can_convert_intype_to_type if (!can_convert_intype_to_type
&& (convtype & CONV_IMPLICIT) && MAYBE_CLASS_TYPE_P (intype) && (convtype & CONV_IMPLICIT) && MAYBE_CLASS_TYPE_P (intype)
...@@ -449,7 +449,8 @@ convert_to_reference (tree reftype, tree expr, int convtype, ...@@ -449,7 +449,8 @@ convert_to_reference (tree reftype, tree expr, int convtype,
} }
} }
if (((convtype & CONV_STATIC) && can_convert (intype, type, complain)) if (((convtype & CONV_STATIC)
&& can_convert_standard (intype, type, complain))
|| ((convtype & CONV_IMPLICIT) && can_convert_intype_to_type)) || ((convtype & CONV_IMPLICIT) && can_convert_intype_to_type))
{ {
{ {
......
...@@ -5854,7 +5854,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ...@@ -5854,7 +5854,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
"because it is of type %qT", expr, type, "because it is of type %qT", expr, type,
TREE_TYPE (expr)); TREE_TYPE (expr));
/* If we are just one standard conversion off, explain. */ /* If we are just one standard conversion off, explain. */
if (can_convert (type, TREE_TYPE (expr), complain)) if (can_convert_standard (type, TREE_TYPE (expr), complain))
inform (input_location, inform (input_location,
"standard conversions are not allowed in this context"); "standard conversions are not allowed in this context");
return NULL_TREE; return NULL_TREE;
......
...@@ -1889,22 +1889,16 @@ check_final_overrider (tree overrider, tree basefn) ...@@ -1889,22 +1889,16 @@ check_final_overrider (tree overrider, tree basefn)
fail = 1; fail = 1;
} }
} }
else if (!pedantic else if (can_convert_standard (TREE_TYPE (base_type),
&& can_convert (TREE_TYPE (base_type), TREE_TYPE (over_type), TREE_TYPE (over_type),
tf_warning_or_error)) tf_warning_or_error))
/* GNU extension, allow trivial pointer conversions such as /* GNU extension, allow trivial pointer conversions such as
converting to void *, or qualification conversion. */ converting to void *, or qualification conversion. */
{ {
/* can_convert will permit user defined conversion from a if (pedwarn (DECL_SOURCE_LOCATION (overrider), 0,
(reference to) class type. We must reject them. */ "invalid covariant return type for %q#D", overrider))
if (CLASS_TYPE_P (non_reference (over_return))) inform (DECL_SOURCE_LOCATION (basefn),
fail = 2; " overriding %q+#D", basefn);
else
{
warning (0, "deprecated covariant return type for %q+#D",
overrider);
warning (0, " overriding %q+#D", basefn);
}
} }
else else
fail = 2; fail = 2;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment