This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

C++ PATCH to expand bad conversion tolerance


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;
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]