diff options
author | Mark Mitchell <mark@codesourcery.com> | 2009-07-02 17:52:37 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2009-07-02 17:52:37 +0000 |
commit | ef3ddd4fa3d29318b5e05886382375712b9c1411 (patch) | |
tree | fd9bab8aa6e746e12c41996a03231a4540cf1e4c /gcc | |
parent | 2b110bfcc074f222a49d875c5f0f5ea370294b9f (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 39 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/null4.C | 26 |
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; } |