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
This commit is contained in:
parent
e43257e817
commit
53db1bc08e
@ -1,3 +1,13 @@
|
||||
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>
|
||||
|
||||
PR c++/57869
|
||||
|
@ -8813,6 +8813,20 @@ tourney (struct z_candidate *candidates, tsubst_flags_t complain)
|
||||
|
||||
bool
|
||||
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);
|
||||
}
|
||||
|
@ -5007,6 +5007,7 @@ extern tree build_op_delete_call (enum tree_code, tree, tree,
|
||||
bool, 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,
|
||||
tsubst_flags_t);
|
||||
extern bool can_convert_arg_bad (tree, tree, tree, int,
|
||||
|
@ -428,7 +428,7 @@ convert_to_reference (tree reftype, tree expr, int convtype,
|
||||
|
||||
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
|
||||
&& (convtype & CONV_IMPLICIT) && MAYBE_CLASS_TYPE_P (intype)
|
||||
@ -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))
|
||||
{
|
||||
{
|
||||
|
@ -5854,7 +5854,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
|
||||
"because it is of type %qT", expr, type,
|
||||
TREE_TYPE (expr));
|
||||
/* 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,
|
||||
"standard conversions are not allowed in this context");
|
||||
return NULL_TREE;
|
||||
|
@ -1889,22 +1889,16 @@ check_final_overrider (tree overrider, tree basefn)
|
||||
fail = 1;
|
||||
}
|
||||
}
|
||||
else if (!pedantic
|
||||
&& can_convert (TREE_TYPE (base_type), TREE_TYPE (over_type),
|
||||
tf_warning_or_error))
|
||||
else if (can_convert_standard (TREE_TYPE (base_type),
|
||||
TREE_TYPE (over_type),
|
||||
tf_warning_or_error))
|
||||
/* GNU extension, allow trivial pointer conversions such as
|
||||
converting to void *, or qualification conversion. */
|
||||
{
|
||||
/* can_convert will permit user defined conversion from a
|
||||
(reference to) class type. We must reject them. */
|
||||
if (CLASS_TYPE_P (non_reference (over_return)))
|
||||
fail = 2;
|
||||
else
|
||||
{
|
||||
warning (0, "deprecated covariant return type for %q+#D",
|
||||
overrider);
|
||||
warning (0, " overriding %q+#D", basefn);
|
||||
}
|
||||
if (pedwarn (DECL_SOURCE_LOCATION (overrider), 0,
|
||||
"invalid covariant return type for %q#D", overrider))
|
||||
inform (DECL_SOURCE_LOCATION (basefn),
|
||||
" overriding %q+#D", basefn);
|
||||
}
|
||||
else
|
||||
fail = 2;
|
||||
|
Loading…
x
Reference in New Issue
Block a user