C++ PATCH to expand bad conversion tolerance
Jason Merrill
jason_merrill@redhat.com
Tue Oct 9 08:19:00 GMT 2001
This patch reintroduces support for bad conversion between pointers and
integers, and from void* to other pointer types, as supported by the old
convert_for_initialization. Use of any such conversions will produce an
unconditional pedwarn from convert_like_real.
Note that this patch is a net simplification...
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.
Index: call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.284
diff -c -p -r1.284 call.c
*** call.c 2001/10/02 07:19:45 1.284
--- call.c 2001/10/09 15:00:49
*************** standard_conversion (to, from, expr)
*** 745,750 ****
--- 745,758 ----
{
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));
*************** convert_like_real (convs, expr, fn, argn
*** 3750,3758 ****
else if (TREE_CODE (t) == IDENTITY_CONV)
break;
}
! return convert_for_initialization
! (NULL_TREE, totype, expr, LOOKUP_NORMAL,
! "conversion", fn, argnum);
}
if (!inner)
--- 3758,3767 ----
else if (TREE_CODE (t) == IDENTITY_CONV)
break;
}
! 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)
*************** build_over_call (cand, args, flags)
*** 4152,4184 ****
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);
- }
-
if (PROMOTE_PROTOTYPES
&& INTEGRAL_TYPE_P (type)
&& (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
--- 4161,4169 ----
tree type = TREE_VALUE (parm);
conv = TREE_VEC_ELT (convs, i);
! val = convert_like_with_context
! (conv, TREE_VALUE (arg), fn, i - is_method);
if (PROMOTE_PROTOTYPES
&& INTEGRAL_TYPE_P (type)
&& (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
*************** can_convert_arg (to, from, arg)
*** 5550,5557 ****
return (t && ! ICS_BAD_FLAG (t));
}
! /* Convert EXPR to TYPE. Return the converted expression. */
tree
perform_implicit_conversion (type, expr)
tree type;
--- 5535,5556 ----
return (t && ! ICS_BAD_FLAG (t));
}
! /* 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)
tree type;
*************** perform_implicit_conversion (type, expr)
*** 5563,5569 ****
return error_mark_node;
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
LOOKUP_NORMAL);
! if (!conv || ICS_BAD_FLAG (conv))
{
cp_error ("could not convert `%E' to `%T'", expr, type);
return error_mark_node;
--- 5562,5568 ----
return error_mark_node;
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
LOOKUP_NORMAL);
! if (!conv)
{
cp_error ("could not convert `%E' to `%T'", expr, type);
return error_mark_node;
Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.644
diff -c -p -r1.644 cp-tree.h
*** cp-tree.h 2001/10/02 15:43:43 1.644
--- cp-tree.h 2001/10/09 15:00:49
*************** extern tree build_new_op PARAMS ((enum
*** 3509,3514 ****
--- 3509,3515 ----
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));
Index: typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.366
diff -c -p -r1.366 typeck.c
*** typeck.c 2001/10/02 07:19:46 1.366
--- typeck.c 2001/10/09 15:00:51
*************** convert_for_assignment (type, rhs, errty
*** 6295,6302 ****
/* [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))
{
/* When -Wno-pmf-conversions is use, we just silently allow
conversions from pointers-to-members to plain pointers. If
--- 6295,6306 ----
/* [expr.ass]
The expression is implicitly converted (clause _conv_) to the
! 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
*************** ptr_reasonably_similar (to, from)
*** 6798,6803 ****
--- 6802,6812 ----
{
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;
More information about the Gcc-patches
mailing list