aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2009-07-02 17:52:37 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2009-07-02 17:52:37 +0000
commitef3ddd4fa3d29318b5e05886382375712b9c1411 (patch)
treefd9bab8aa6e746e12c41996a03231a4540cf1e4c /gcc
parent2b110bfcc074f222a49d875c5f0f5ea370294b9f (diff)
downloadgcc-ef3ddd4fa3d29318b5e05886382375712b9c1411.zip
gcc-ef3ddd4fa3d29318b5e05886382375712b9c1411.tar.gz
gcc-ef3ddd4fa3d29318b5e05886382375712b9c1411.tar.bz2
typeck.c (cp_build_binary_op): Move warnings about use of NULL in arithmetic earlier and allow comparisions of...
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 Mark Mitchell <mark@codesourcery.com> * g++.dg/warn/null4.C: Extend. From-SVN: r149190
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/typeck.c39
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/warn/null4.C26
4 files changed, 55 insertions, 20 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9304871..17ac919 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index e502021..871c1d3 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 278c787..5153620 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/g++.dg/warn/null4.C b/gcc/testsuite/g++.dg/warn/null4.C
index 785f279..6aa4a09 100644
--- a/gcc/testsuite/g++.dg/warn/null4.C
+++ b/gcc/testsuite/g++.dg/warn/null4.C
@@ -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;
}