call.c (standard_conversion): Add bad conversion between integers and pointers.

* call.c (standard_conversion): Add bad conversion between
        integers and pointers.
        (convert_like_real): Don't use convert_for_initialization for bad
        conversions; complain here and use cp_convert.
        (build_over_call): Don't handle bad conversions specially.
        (perform_implicit_conversion): Allow bad conversions.
        (can_convert_arg_bad): New fn.
        * cp-tree.h: Declare it.
        * typeck.c (convert_for_assignment): Use it.
        (ptr_reasonably_similar): Any target type is similar to void.

From-SVN: r46123
This commit is contained in:
Jason Merrill 2001-10-09 11:42:44 -04:00
parent 2ba84f36ea
commit 72a08131a5
5 changed files with 77 additions and 35 deletions

View File

@ -1,3 +1,20 @@
2001-10-04 Jason Merrill <jason_merrill@redhat.com>
* call.c (standard_conversion): Add bad conversion between
integers and pointers.
(convert_like_real): Don't use convert_for_initialization for bad
conversions; complain here and use cp_convert.
(build_over_call): Don't handle bad conversions specially.
(perform_implicit_conversion): Allow bad conversions.
(can_convert_arg_bad): New fn.
* cp-tree.h: Declare it.
* typeck.c (convert_for_assignment): Use it.
(ptr_reasonably_similar): Any target type is similar to void.
2001-10-02 Jason Merrill <jason_merrill@redhat.com>
* decl2.c (cxx_decode_option): Add 'else'.
2001-10-08 Alexandre Oliva <aoliva@redhat.com>
* Make-lang.in (CXX_OBJS): Added cp-lang.o.
@ -238,7 +255,7 @@ Fri Sep 21 08:16:19 2001 J"orn Rennecke <amylaar@redhat.com>
CLASSTYPE_PURE_VIRTUALS.
(TYPE_RAISES_EXCEPTIONS): Map onto TYPE_BINFO.
* class.c (duplicate_tag_error): Remove TYPE_NONCOPIED_PARTS.
(layout_class_type): Don't call fixup_inlin_methods here ...
(layout_class_type): Don't call fixup_inline_methods here ...
(finish_struct_1): ... call it here.
2001-09-04 Mark Mitchell <mark@codesourcery.com>

View File

@ -745,6 +745,14 @@ standard_conversion (to, from, expr)
{
conv = build_conv (STD_CONV, to, conv);
}
else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
|| (tcode == POINTER_TYPE && fcode == INTEGER_TYPE))
{
/* For backwards brain damage compatibility, allow interconversion of
pointers and integers with a pedwarn. */
conv = build_conv (STD_CONV, to, conv);
ICS_BAD_FLAG (conv) = 1;
}
else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE)
{
enum tree_code ufcode = TREE_CODE (TREE_TYPE (from));
@ -3750,9 +3758,10 @@ convert_like_real (convs, expr, fn, argnum, inner)
else if (TREE_CODE (t) == IDENTITY_CONV)
break;
}
return convert_for_initialization
(NULL_TREE, totype, expr, LOOKUP_NORMAL,
"conversion", fn, argnum);
cp_pedwarn ("invalid conversion from `%T' to `%T'", TREE_TYPE (expr), totype);
if (fn)
cp_pedwarn (" initializing argument %P of `%D'", argnum, fn);
return cp_convert (totype, expr);
}
if (!inner)
@ -4152,32 +4161,8 @@ build_over_call (cand, args, flags)
tree type = TREE_VALUE (parm);
conv = TREE_VEC_ELT (convs, i);
if (ICS_BAD_FLAG (conv))
{
tree t = conv;
val = TREE_VALUE (arg);
for (; t; t = TREE_OPERAND (t, 0))
{
if (TREE_CODE (t) == USER_CONV
|| TREE_CODE (t) == AMBIG_CONV)
{
val = convert_like_with_context (t, val, fn, i - is_method);
break;
}
else if (TREE_CODE (t) == IDENTITY_CONV)
break;
}
val = convert_for_initialization
(NULL_TREE, type, val, LOOKUP_NORMAL,
"argument", fn, i - is_method);
}
else
{
val = TREE_VALUE (arg);
val = convert_like_with_context
(conv, TREE_VALUE (arg), fn, i - is_method);
}
val = convert_like_with_context
(conv, TREE_VALUE (arg), fn, i - is_method);
if (PROMOTE_PROTOTYPES
&& INTEGRAL_TYPE_P (type)
@ -5550,7 +5535,21 @@ can_convert_arg (to, from, arg)
return (t && ! ICS_BAD_FLAG (t));
}
/* Convert EXPR to TYPE. Return the converted expression. */
/* Like can_convert_arg, but allows dubious conversions as well. */
int
can_convert_arg_bad (to, from, arg)
tree to, from, arg;
{
tree t = implicit_conversion (to, from, arg, LOOKUP_NORMAL);
return !!t;
}
/* Convert EXPR to TYPE. Return the converted expression.
Note that we allow bad conversions here because by the time we get to
this point we are committed to doing the conversion. If we end up
doing a bad conversion, convert_like will complain. */
tree
perform_implicit_conversion (type, expr)
@ -5563,7 +5562,7 @@ perform_implicit_conversion (type, expr)
return error_mark_node;
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
LOOKUP_NORMAL);
if (!conv || ICS_BAD_FLAG (conv))
if (!conv)
{
cp_error ("could not convert `%E' to `%T'", expr, type);
return error_mark_node;

View File

@ -3489,6 +3489,7 @@ extern tree build_new_op PARAMS ((enum tree_code, int, tree, tree, tree));
extern tree build_op_delete_call PARAMS ((enum tree_code, tree, tree, int, tree));
extern int can_convert PARAMS ((tree, tree));
extern int can_convert_arg PARAMS ((tree, tree, tree));
extern int can_convert_arg_bad PARAMS ((tree, tree, tree));
extern int enforce_access PARAMS ((tree, tree));
extern tree convert_default_arg PARAMS ((tree, tree, tree, int));
extern tree convert_arg_to_ellipsis PARAMS ((tree));

View File

@ -6295,8 +6295,12 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
/* [expr.ass]
The expression is implicitly converted (clause _conv_) to the
cv-unqualified type of the left operand. */
if (!can_convert_arg (type, rhstype, rhs))
cv-unqualified type of the left operand.
We allow bad conversions here because by the time we get to this point
we are committed to doing the conversion. If we end up doing a bad
conversion, convert_like will complain. */
if (!can_convert_arg_bad (type, rhstype, rhs))
{
/* When -Wno-pmf-conversions is use, we just silently allow
conversions from pointers-to-members to plain pointers. If
@ -6305,7 +6309,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
&& TYPE_PTR_P (type)
&& TYPE_PTRMEMFUNC_P (rhstype))
rhs = cp_convert (strip_top_quals (type), rhs);
else
else
{
/* If the right-hand side has unknown type, then it is an
overloaded function. Call instantiate_type to get error
@ -6798,6 +6802,11 @@ ptr_reasonably_similar (to, from)
{
for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
{
/* Any target type is similar enough to void. */
if (TREE_CODE (to) == VOID_TYPE
|| TREE_CODE (from) == VOID_TYPE)
return 1;
if (TREE_CODE (to) != TREE_CODE (from))
return 0;

View File

@ -0,0 +1,16 @@
// Test for backwards brain-damage compatibility with -fpermissive.
// { dg-options "-fpermissive -w" }
void f ();
void f (int *);
void g (int);
int main ()
{
void *v = 1234;
void (*p)() = v;
int i = v;
f (i);
f (v);
g (v);
}