[C++ PATCH]: warning on implicit float->int

Nathan Sidwell nathan@codesourcery.com
Sun Mar 5 02:26:00 GMT 2000


Mark Mitchell wrote:

> Please check in the patch with those changes.  And thanks!

I checked in the attached. There was a test case with the original
version of the patch, I forgot to copy it in the updated version

nathan

-- 
Dr Nathan Sidwell   ::   http://www.codesourcery.com   ::   CodeSourcery LLC
         'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2000-03-05  Nathan Sidwell  <nathan@codesourcery.com>

	* call.c (convert_like): Macrofy.
	(convert_like_with_context): New macro.
	(convert_like_real): Renamed from convert_like.  Add calling
	context parameters, for diagnostics. Add recursive flag.  Call 
	dubious_conversion_warnings for outer conversion.
	(build_user_type_conversion): Use convert_like_with_context.
	(build_over_call): Likewise. Don't warn about dubious
	conversions here. Adjust convert_default_arg calls.
	(convert_default_arg): Add context parameters for diagnostics.
	Pass throught to convert_like_with_context.
	* cp-tree.h (convert_default_arg): Add context parameters.
	(dubious_conversion_warnings): Prototype new function.
	* typeck.c (convert_arguments): Adjust convert_default_arg call.
	(dubious_conversion_warnings): New function, broken
	out of convert_for_assignment. 
	(convert_for_assignment): Adjust.

Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/call.c,v
retrieving revision 1.199
diff -c -3 -p -r1.199 call.c
*** call.c	2000/03/03 02:27:14	1.199
--- call.c	2000/03/05 09:49:33
*************** static int equal_functions PARAMS ((tree
*** 49,55 ****
  static int joust PARAMS ((struct z_candidate *, struct z_candidate *, int));
  static int compare_ics PARAMS ((tree, tree));
  static tree build_over_call PARAMS ((struct z_candidate *, tree, int));
! static tree convert_like PARAMS ((tree, tree));
  static void op_error PARAMS ((enum tree_code, enum tree_code, tree, tree,
  			    tree, const char *));
  static tree build_object_call PARAMS ((tree, tree));
--- 49,57 ----
  static int joust PARAMS ((struct z_candidate *, struct z_candidate *, int));
  static int compare_ics PARAMS ((tree, tree));
  static tree build_over_call PARAMS ((struct z_candidate *, tree, int));
! #define convert_like(CONV, EXPR) convert_like_real (CONV, EXPR, NULL_TREE, 0, 0)
! #define convert_like_with_context(CONV, EXPR, FN, ARGNO) convert_like_real (CONV, EXPR, FN, ARGNO, 0)
! static tree convert_like_real PARAMS ((tree, tree, tree, int, int));
  static void op_error PARAMS ((enum tree_code, enum tree_code, tree, tree,
  			    tree, const char *));
  static tree build_object_call PARAMS ((tree, tree));
*************** build_user_type_conversion (totype, expr
*** 2450,2456 ****
      {
        if (TREE_CODE (cand->second_conv) == AMBIG_CONV)
  	return error_mark_node;
!       return convert_from_reference (convert_like (cand->second_conv, expr));
      }
    return NULL_TREE;
  }
--- 2452,2460 ----
      {
        if (TREE_CODE (cand->second_conv) == AMBIG_CONV)
  	return error_mark_node;
!       return convert_from_reference
!               (convert_like_with_context
!                 (cand->second_conv, expr, cand->fn, 0));
      }
    return NULL_TREE;
  }
*************** build_object_call (obj, args)
*** 2654,2660 ****
        && DECL_NAME (cand->fn) == ansi_opname [CALL_EXPR])
      return build_over_call (cand, mem_args, LOOKUP_NORMAL);
  
!   obj = convert_like (TREE_VEC_ELT (cand->convs, 0), obj);
  
    /* FIXME */
    return build_function_call (obj, args);
--- 2658,2665 ----
        && DECL_NAME (cand->fn) == ansi_opname [CALL_EXPR])
      return build_over_call (cand, mem_args, LOOKUP_NORMAL);
  
!   obj = convert_like_with_context
!           (TREE_VEC_ELT (cand->convs, 0), obj, cand->fn, -1);
  
    /* FIXME */
    return build_function_call (obj, args);
*************** enforce_access (basetype_path, decl)
*** 3593,3603 ****
    return 1;
  }
  
! /* Perform the conversions in CONVS on the expression EXPR.  */
  
  static tree
! convert_like (convs, expr)
       tree convs, expr;
  {
    if (ICS_BAD_FLAG (convs)
        && TREE_CODE (convs) != USER_CONV
--- 3598,3614 ----
    return 1;
  }
  
! /* Perform the conversions in CONVS on the expression EXPR. 
!    FN and ARGNUM are used for diagnostics.  ARGNUM is zero based, -1
!    indicates the `this' argument of a method.  INNER is non-zero when
!    being called to continue a conversion chain. */
  
  static tree
! convert_like_real (convs, expr, fn, argnum, inner)
       tree convs, expr;
+      tree fn;
+      int argnum;
+      int inner;
  {
    if (ICS_BAD_FLAG (convs)
        && TREE_CODE (convs) != USER_CONV
*************** convert_like (convs, expr)
*** 3609,3627 ****
  	{
  	  if (TREE_CODE (t) == USER_CONV)
  	    {
! 	      expr = convert_like (t, expr);
  	      break;
  	    }
  	  else if (TREE_CODE (t) == AMBIG_CONV)
! 	    return convert_like (t, expr);
  	  else if (TREE_CODE (t) == IDENTITY_CONV)
  	    break;
  	}
        return convert_for_initialization
  	(NULL_TREE, TREE_TYPE (convs), expr, LOOKUP_NORMAL,
! 	 "conversion", NULL_TREE, 0);
      }
! 
    switch (TREE_CODE (convs))
      {
      case USER_CONV:
--- 3620,3641 ----
  	{
  	  if (TREE_CODE (t) == USER_CONV)
  	    {
! 	      expr = convert_like_real (t, expr, fn, argnum, 1);
  	      break;
  	    }
  	  else if (TREE_CODE (t) == AMBIG_CONV)
! 	    return convert_like_real (t, expr, fn, argnum, 1);
  	  else if (TREE_CODE (t) == IDENTITY_CONV)
  	    break;
  	}
        return convert_for_initialization
  	(NULL_TREE, TREE_TYPE (convs), expr, LOOKUP_NORMAL,
! 	 "conversion", fn, argnum);
      }
!   
!   if (!inner)
!     expr = dubious_conversion_warnings
!              (TREE_TYPE (convs), expr, "argument", fn, argnum);
    switch (TREE_CODE (convs))
      {
      case USER_CONV:
*************** convert_like (convs, expr)
*** 3665,3671 ****
        break;
      };
  
!   expr = convert_like (TREE_OPERAND (convs, 0), expr);
    if (expr == error_mark_node)
      return error_mark_node;
  
--- 3679,3685 ----
        break;
      };
  
!   expr = convert_like_real (TREE_OPERAND (convs, 0), expr, fn, argnum, 1);
    if (expr == error_mark_node)
      return error_mark_node;
  
*************** convert_type_from_ellipsis (type)
*** 3840,3849 ****
     conversions.  Return the converted value.  */
  
  tree
! convert_default_arg (type, arg, fn)
       tree type;
       tree arg;
       tree fn;
  {
    if (fn && DECL_TEMPLATE_INFO (fn))
      arg = tsubst_default_argument (fn, type, arg);
--- 3854,3864 ----
     conversions.  Return the converted value.  */
  
  tree
! convert_default_arg (type, arg, fn, parmnum)
       tree type;
       tree arg;
       tree fn;
+      int parmnum;
  {
    if (fn && DECL_TEMPLATE_INFO (fn))
      arg = tsubst_default_argument (fn, type, arg);
*************** convert_default_arg (type, arg, fn)
*** 3854,3860 ****
      {
        arg = digest_init (type, arg, 0);
        arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
! 					"default argument", 0, 0);
      }
    else
      {
--- 3869,3875 ----
      {
        arg = digest_init (type, arg, 0);
        arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
! 					"default argument", fn, parmnum);
      }
    else
      {
*************** convert_default_arg (type, arg, fn)
*** 3863,3869 ****
  	arg = copy_node (arg);
  
        arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
! 					"default argument", 0, 0);
        if (PROMOTE_PROTOTYPES
  	  && (TREE_CODE (type) == INTEGER_TYPE
  	      || TREE_CODE (type) == ENUMERAL_TYPE)
--- 3878,3884 ----
  	arg = copy_node (arg);
  
        arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL,
! 					"default argument", fn, parmnum);
        if (PROMOTE_PROTOTYPES
  	  && (TREE_CODE (type) == INTEGER_TYPE
  	      || TREE_CODE (type) == ENUMERAL_TYPE)
*************** build_over_call (cand, args, flags)
*** 3956,3962 ****
  	      if (TREE_CODE (t) == USER_CONV
  		  || TREE_CODE (t) == AMBIG_CONV)
  		{
! 		  val = convert_like (t, val);
  		  break;
  		}
  	      else if (TREE_CODE (t) == IDENTITY_CONV)
--- 3971,3977 ----
  	      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)
*************** build_over_call (cand, args, flags)
*** 3964,3979 ****
  	    }
  	  val = convert_for_initialization
  	    (NULL_TREE, type, val, LOOKUP_NORMAL,
! 	     "argument passing", fn, i - is_method);
  	}
        else
  	{
! 	  /* Issue warnings about peculiar, but legal, uses of NULL.  */
! 	  if (ARITHMETIC_TYPE_P (TREE_VALUE (parm))
! 	      && TREE_VALUE (arg) == null_node)
! 	    cp_warning ("converting NULL to non-pointer type");
! 	    
! 	  val = convert_like (conv, TREE_VALUE (arg));
  	}
  
        if (PROMOTE_PROTOTYPES
--- 3979,3991 ----
  	    }
  	  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
*************** build_over_call (cand, args, flags)
*** 3985,3996 ****
      }
  
    /* Default arguments */
!   for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm))
      converted_args 
        = tree_cons (NULL_TREE, 
  		   convert_default_arg (TREE_VALUE (parm), 
  					TREE_PURPOSE (parm),
! 					fn),
  		   converted_args);
  
    /* Ellipsis */
--- 3997,4008 ----
      }
  
    /* Default arguments */
!   for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm), i++)
      converted_args 
        = tree_cons (NULL_TREE, 
  		   convert_default_arg (TREE_VALUE (parm), 
  					TREE_PURPOSE (parm),
! 					fn, i - is_method),
  		   converted_args);
  
    /* Ellipsis */
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.412
diff -c -3 -p -r1.412 cp-tree.h
*** cp-tree.h	2000/03/03 02:27:14	1.412
--- cp-tree.h	2000/03/05 09:49:35
*************** extern tree build_op_delete_call		PARAMS
*** 3616,3622 ****
  extern int can_convert				PARAMS ((tree, tree));
  extern int can_convert_arg			PARAMS ((tree, tree, tree));
  extern int enforce_access                       PARAMS ((tree, tree));
! extern tree convert_default_arg                 PARAMS ((tree, tree, tree));
  extern tree convert_arg_to_ellipsis             PARAMS ((tree));
  extern tree build_x_va_arg                      PARAMS ((tree, tree));
  extern tree convert_type_from_ellipsis          PARAMS ((tree));
--- 3616,3622 ----
  extern int can_convert				PARAMS ((tree, tree));
  extern int can_convert_arg			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));
  extern tree build_x_va_arg                      PARAMS ((tree, tree));
  extern tree convert_type_from_ellipsis          PARAMS ((tree));
*************** extern tree build_const_cast			PARAMS ((
*** 4407,4412 ****
--- 4407,4413 ----
  extern tree build_c_cast			PARAMS ((tree, tree));
  extern tree build_x_modify_expr			PARAMS ((tree, enum tree_code, tree));
  extern tree build_modify_expr			PARAMS ((tree, enum tree_code, tree));
+ extern tree dubious_conversion_warnings         PARAMS ((tree, tree, const char *, tree, int));
  extern tree convert_for_initialization		PARAMS ((tree, tree, tree, int, const char *, tree, int));
  extern void c_expand_asm_operands		PARAMS ((tree, tree, tree, tree, int, char *, int));
  extern void c_expand_return			PARAMS ((tree));
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.256
diff -c -3 -p -r1.256 typeck.c
*** typeck.c	2000/03/03 02:27:15	1.256
--- typeck.c	2000/03/05 09:49:42
*************** convert_arguments (typelist, values, fnd
*** 3215,3221 ****
  	      tree parmval 
  		= convert_default_arg (TREE_VALUE (typetail), 
  				       TREE_PURPOSE (typetail), 
! 				       fndecl);
  
  	      if (parmval == error_mark_node)
  		return error_mark_node;
--- 3215,3221 ----
  	      tree parmval 
  		= convert_default_arg (TREE_VALUE (typetail), 
  				       TREE_PURPOSE (typetail), 
! 				       fndecl, i);
  
  	      if (parmval == error_mark_node)
  		return error_mark_node;
*************** pfn_from_ptrmemfunc (t)
*** 6421,6426 ****
--- 6421,6479 ----
  	     pfn_identifier, NULL_TREE, 0)); 
  }
  
+ /* Expression EXPR is about to be implicitly converted to TYPE.  Warn
+    if this is a potentially dangerous thing to do.  Returns a possibly
+    marked EXPR.  */
+ 
+ tree
+ dubious_conversion_warnings (type, expr, errtype, fndecl, parmnum)
+      tree type;
+      tree expr;
+      const char *errtype;
+      tree fndecl;
+      int parmnum;
+ {
+   /* Issue warnings about peculiar, but legal, uses of NULL.  */
+   if (ARITHMETIC_TYPE_P (type) && expr == null_node)
+     {
+       if (fndecl)
+         cp_warning ("passing NULL used for non-pointer %s %P of `%D'",
+                     errtype, parmnum, fndecl);
+       else
+         cp_warning ("%s to non-pointer type `%T' from NULL", errtype, type);
+     }
+   
+   /* Warn about assigning a floating-point type to an integer type.  */
+   if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
+       && TREE_CODE (type) == INTEGER_TYPE)
+     {
+       if (fndecl)
+ 	cp_warning ("passing `%T' for %s %P of `%D'",
+ 		    TREE_TYPE (expr), errtype, parmnum, fndecl);
+       else
+ 	cp_warning ("%s to `%T' from `%T'", errtype, type, TREE_TYPE (expr));
+     }
+   /* And warn about assigning a negative value to an unsigned
+      variable.  */
+   else if (TREE_UNSIGNED (type) && TREE_CODE (type) != BOOLEAN_TYPE)
+     {
+       if (TREE_CODE (expr) == INTEGER_CST
+ 	  && TREE_NEGATED_INT (expr))
+ 	{
+ 	  if (fndecl)
+ 	    cp_warning ("passing negative value `%E' for %s %P of `%D'",
+ 			expr, errtype, parmnum, fndecl);
+ 	  else
+ 	    cp_warning ("%s of negative value `%E' to `%T'",
+ 			errtype, expr, type);
+ 	}
+       overflow_warning (expr);
+       if (TREE_CONSTANT (expr))
+ 	expr = fold (expr);
+     }
+   return expr;
+ }
+ 
  /* Convert value RHS to type TYPE as preparation for an assignment to
     an lvalue of type TYPE.  ERRTYPE is a string to use in error
     messages: "assignment", "return", etc.  If FNDECL is non-NULL, we
*************** convert_for_assignment (type, rhs, errty
*** 6456,6467 ****
    if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
      return error_mark_node;
  
!   /* Issue warnings about peculiar, but legal, uses of NULL.  We
!      do this *before* the call to decl_constant_value so as to
!      avoid duplicate warnings on code like `const int I = NULL;
!      f(I);'.  */
!   if (ARITHMETIC_TYPE_P (type) && rhs == null_node)
!     cp_warning ("converting NULL to non-pointer type");
  
    /* The RHS of an assignment cannot have void type.  */
    if (coder == VOID_TYPE)
--- 6509,6515 ----
    if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
      return error_mark_node;
  
!   rhs = dubious_conversion_warnings (type, rhs, errtype, fndecl, parmnum);
  
    /* The RHS of an assignment cannot have void type.  */
    if (coder == VOID_TYPE)
*************** convert_for_assignment (type, rhs, errty
*** 6475,6508 ****
      rhs = DECL_INITIAL (rhs);
    else if (TREE_READONLY_DECL_P (rhs))
      rhs = decl_constant_value (rhs);
- 
-   /* Warn about assigning a floating-point type to an integer type.  */
-   if (coder == REAL_TYPE && codel == INTEGER_TYPE)
-     {
-       if (fndecl)
- 	cp_warning ("`%T' used for argument %P of `%D'",
- 		    rhstype, parmnum, fndecl);
-       else
- 	cp_warning ("%s to `%T' from `%T'", errtype, type, rhstype);
-     }
-   /* And warn about assigning a negative value to an unsigned
-      variable.  */
-   else if (TREE_UNSIGNED (type) && codel != BOOLEAN_TYPE)
-     {
-       if (TREE_CODE (rhs) == INTEGER_CST
- 	  && TREE_NEGATED_INT (rhs))
- 	{
- 	  if (fndecl)
- 	    cp_warning ("negative value `%E' passed as argument %P of `%D'",
- 			rhs, parmnum, fndecl);
- 	  else
- 	    cp_warning ("%s of negative value `%E' to `%T'",
- 			errtype, rhs, type);
- 	}
-       overflow_warning (rhs);
-       if (TREE_CONSTANT (rhs))
- 	rhs = fold (rhs);
-     }
  
    /* [expr.ass]
  
--- 6523,6528 ----


More information about the Gcc-patches mailing list