OSDN Git Service

2009-07-02 Mark Mitchell <mark@codesourcery.com>
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 2 Jul 2009 17:52:37 +0000 (17:52 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 2 Jul 2009 17:52:37 +0000 (17:52 +0000)
* typeck.c (cp_build_binary_op): Move warnings about use of NULL
in arithmetic earlier and allow comparisions of NULL with
pointers-to-members.

2009-07-02  Mark Mitchell  <mark@codesourcery.com>

* g++.dg/warn/null4.C: Extend.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149190 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/null4.C

index 9304871..17ac919 100644 (file)
@@ -1,3 +1,9 @@
+2009-07-02  Mark Mitchell  <mark@codesourcery.com>
+
+       * typeck.c (cp_build_binary_op): Move warnings about use of NULL
+       in arithmetic earlier and allow comparisions of NULL with
+       pointers-to-members.
+
 2009-07-02  Jason Merrill  <jason@redhat.com>
 
        Use hash tables for template specialization lookup.
index e502021..871c1d3 100644 (file)
@@ -3419,7 +3419,6 @@ cp_build_binary_op (location_t location,
 
   /* If an error was already reported for one of the arguments,
      avoid reporting another error.  */
-
   if (code0 == ERROR_MARK || code1 == ERROR_MARK)
     return error_mark_node;
 
@@ -3430,6 +3429,25 @@ cp_build_binary_op (location_t location,
       return error_mark_node;
     }
 
+  /* Issue warnings about peculiar, but valid, uses of NULL.  */
+  if ((orig_op0 == null_node || orig_op1 == null_node)
+      /* It's reasonable to use pointer values as operands of &&
+        and ||, so NULL is no exception.  */
+      && code != TRUTH_ANDIF_EXPR && code != TRUTH_ORIF_EXPR 
+      && ( /* Both are NULL (or 0) and the operation was not a
+             comparison or a pointer subtraction.  */
+         (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1) 
+          && code != EQ_EXPR && code != NE_EXPR && code != MINUS_EXPR) 
+         /* Or if one of OP0 or OP1 is neither a pointer nor NULL.  */
+         || (!null_ptr_cst_p (orig_op0)
+             && !TYPE_PTR_P (type0) && !TYPE_PTR_TO_MEMBER_P (type0))
+         || (!null_ptr_cst_p (orig_op1) 
+             && !TYPE_PTR_P (type1) && !TYPE_PTR_TO_MEMBER_P (type1)))
+      && (complain & tf_warning))
+    /* Some sort of arithmetic operation involving NULL was
+       performed.  */
+    warning (OPT_Wpointer_arith, "NULL used in arithmetic");
+
   switch (code)
     {
     case MINUS_EXPR:
@@ -4031,25 +4049,6 @@ cp_build_binary_op (location_t location,
        }
     }
 
-  /* Issue warnings about peculiar, but valid, uses of NULL.  */
-  if ((orig_op0 == null_node || orig_op1 == null_node)
-      /* It's reasonable to use pointer values as operands of &&
-        and ||, so NULL is no exception.  */
-      && code != TRUTH_ANDIF_EXPR && code != TRUTH_ORIF_EXPR 
-      && ( /* Both are NULL (or 0) and the operation was not a comparison.  */
-         (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1) 
-          && code != EQ_EXPR && code != NE_EXPR) 
-         /* Or if one of OP0 or OP1 is neither a pointer nor NULL.  */
-         || (!null_ptr_cst_p (orig_op0) && TREE_CODE (TREE_TYPE (op0)) != POINTER_TYPE)
-         || (!null_ptr_cst_p (orig_op1) && TREE_CODE (TREE_TYPE (op1)) != POINTER_TYPE))
-      && (complain & tf_warning))
-    /* 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.  */
-    warning (OPT_Wpointer_arith, "NULL used in arithmetic");
-  
-
   /* If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
      Then the expression will be built.
      It will be given type FINAL_TYPE if that is nonzero;
index 278c787..5153620 100644 (file)
@@ -1,3 +1,7 @@
+2009-07-02  Mark Mitchell  <mark@codesourcery.com>
+
+       * g++.dg/warn/null4.C: Extend.
+
 2009-07-02  Jason Merrill  <jason@redhat.com>
 
        * g++.dg/template/spec8.C: Fix.
index 785f279..6aa4a09 100644 (file)
@@ -11,9 +11,22 @@ int foo (void)
   if (NULL < NULL) return -1; // { dg-warning "NULL used in arithmetic" } 
   if (NULL >= 0) return -1;   // { dg-warning "NULL used in arithmetic" } 
   if (NULL <= 0) return -1;   // { dg-warning "NULL used in arithmetic" } 
+  // Adding to the NULL pointer, which has no specific type, should
+  // result in a warning; the type of the resulting expression is
+  // actually "int", not a pointer type.
+  if (NULL + 1) return -1;    // { dg-warning "NULL used in arithmetic" }
+  if (1 + NULL) return -1;    // { dg-warning "NULL used in arithmetic" }
   return 0;
 }
 
+int *ip;
+
+struct S {};
+typedef int S::*SPD;
+typedef void (S::*SPF)(void);
+SPD spd;
+SPF spf;
+
 int bar (void) 
 {
   if (NULL) return -1;
@@ -25,5 +38,18 @@ int bar (void)
   if (NULL != NULL) return -1;
   if (NULL == 0) return -1;
   if (NULL != 0) return -1;
+  // Subtraction of pointers is vaild, so using NULL is OK.
+  if (ip - NULL) return -1;
+  if (NULL - NULL) return -1;
+  // Comparing NULL with a pointer-to-member is OK.
+  if (NULL == spd) return -1;
+  if (spd == NULL) return -1;
+  if (NULL != spd) return -1;
+  if (spd != NULL) return -1;
+  if (NULL == spf) return -1;
+  if (spf == NULL) return -1;
+  if (NULL != spf) return -1;
+  if (spf != NULL) return -1;
+
   return 0;
 }