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]

PATCH to restore warnings for arithmetic involving NULL



This patch causes warnings, but not errors, for expressions like `i !=
NULL' where `i' is an integer.

This patch has the advantage, over the previous scheme, of issuing
these warnings even when -ansi is used.  (The constructs are just as
suspect in that case.)  Similarly, I've changed build_throw so that
`throw NULL' always reults in a warning.  And, in that case, we
shouldn't have been using integer_zero_node for NULL; that might not
be a zero of the correct size.

-- 
Mark Mitchell 			mark@markmitchell.com
Mark Mitchell Consulting	http://www.markmitchell.com

1998-08-19  Mark Mitchell  <mark@markmitchell.com>

	* typeck.c (build_binary_op_nodefault): Warn on use of NULL in
	arithmetic.
	* except.c (build_throw): Warn when NULL is thrown, even with
	-ansi.  Use ansi_null_node, rather than integer_zero_node, in the
	thrown expression.

Index: testsuite/g++.old-deja/g++.other/null1.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.other/null1.C,v
retrieving revision 1.1
diff -c -p -r1.1 null1.C
*** null1.C	1998/08/19 15:14:51	1.1
--- null1.C	1998/08/20 01:42:44
*************** void f()
*** 7,12 ****
    int i;
    float f;
  
!   i != NULL;
!   f != NULL;
  }
--- 7,12 ----
    int i;
    float f;
  
!   i != NULL; // WARNING - NULL used in arithmetic
!   f != NULL; // WARNING - NULL used in arithmetic
  }
Index: cp/typeck.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/typeck.c,v
retrieving revision 1.95
diff -c -p -r1.95 typeck.c
*** typeck.c	1998/08/19 15:14:58	1.95
--- typeck.c	1998/08/20 01:43:07
*************** build_binary_op_nodefault (code, orig_op
*** 3248,3270 ****
       things like `7 != NULL' result in errors about comparisons
       between pointers and integers.  So, here, we replace __null with
       an appropriate null pointer constant.  */
!   if (orig_op0 == null_node)
!     orig_op0 = ansi_null_node;
!   if (orig_op1 == null_node)
!     orig_op1 = ansi_null_node;
  
    /* Apply default conversions.  */
    if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
        || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
        || code == TRUTH_XOR_EXPR)
      {
!       op0 = decay_conversion (orig_op0);
!       op1 = decay_conversion (orig_op1);
      }
    else
      {
!       op0 = default_conversion (orig_op0);
!       op1 = default_conversion (orig_op1);
      }
  
    type0 = TREE_TYPE (op0);
--- 3248,3268 ----
       things like `7 != NULL' result in errors about comparisons
       between pointers and integers.  So, here, we replace __null with
       an appropriate null pointer constant.  */
!   op0 = (orig_op0 == null_node) ? ansi_null_node : orig_op0;
!   op1 = (orig_op1 == null_node) ? ansi_null_node : orig_op1;
  
    /* Apply default conversions.  */
    if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
        || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
        || code == TRUTH_XOR_EXPR)
      {
!       op0 = decay_conversion (op0);
!       op1 = decay_conversion (op1);
      }
    else
      {
!       op0 = default_conversion (op0);
!       op1 = default_conversion (op1);
      }
  
    type0 = TREE_TYPE (op0);
*************** build_binary_op_nodefault (code, orig_op
*** 3962,3967 ****
--- 3960,3980 ----
  		TREE_TYPE (orig_op0), TREE_TYPE (orig_op1), error_code);
        return error_mark_node;
      }
+ 
+   if (/* If OP0 is NULL and OP1 is not a pointer, or vice versa.  */
+       (orig_op0 == null_node
+        && TREE_CODE (TREE_TYPE (orig_op1)) != POINTER_TYPE)
+       /* Or vice versa.  */
+       || (orig_op1 == null_node
+ 	  && TREE_CODE (TREE_TYPE (orig_op0)) != POINTER_TYPE)
+       /* Or, both are NULL and the operation was not a comparison.  */
+       || (orig_op0 == null_node && orig_op1 == null_node 
+ 	  && code != EQ_EXPR && code != NE_EXPR))
+     /* Some sort of arithmetic operation involving NULL was
+        performed.  Note that pointer-difference and pointer-addition
+        have already been handled above, and so we don't end up here in
+        that case.  */
+     cp_warning ("NULL used in arithmetic");
  
    if (! converted)
      {
Index: cp/except.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/except.c,v
retrieving revision 1.46
diff -c -p -r1.46 except.c
*** except.c	1998/07/24 12:36:53	1.46
--- except.c	1998/08/20 01:43:10
*************** build_throw (e)
*** 1277,1286 ****
    if (processing_template_decl)
      return build_min (THROW_EXPR, void_type_node, e);
  
!   if (! flag_ansi && e == null_node)
      {
!       cp_warning ("throwing NULL");
!       e = integer_zero_node;
      }
  
    e = build1 (THROW_EXPR, void_type_node, e);
--- 1277,1286 ----
    if (processing_template_decl)
      return build_min (THROW_EXPR, void_type_node, e);
  
!   if (e == null_node)
      {
!       cp_warning ("throwing NULL, which has integral, not pointer type");
!       e = ansi_null_node;
      }
  
    e = build1 (THROW_EXPR, void_type_node, e);


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