diff options
author | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-03-04 19:03:13 +0000 |
---|---|---|
committer | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-03-04 19:03:13 +0000 |
commit | 626b33bbb4413c12337b31ecbacaf32137146376 (patch) | |
tree | a609ca95a2be9b1ca5061bfa82fdba65079759d8 | |
parent | 13f97a32663b7d1cef14f0c1976f14c920b73381 (diff) | |
download | ppe42-gcc-626b33bbb4413c12337b31ecbacaf32137146376.tar.gz ppe42-gcc-626b33bbb4413c12337b31ecbacaf32137146376.zip |
PR middle-end/30744
* fold-const.c (fold_comparison): Enforce type consistency when
transforming ~X op ~Y to Y op X, and ~X op C to X op' ~C.
* gcc.dg/pr30744-1.c: New test case.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122531 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fold-const.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr30744-1.c | 15 |
4 files changed, 39 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index aaf8321174e..2646f347f16 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2007-03-04 Roger Sayle <roger@eyesopen.com> + + PR middle-end/30744 + * fold-const.c (fold_comparison): Enforce type consistency when + transforming ~X op ~Y to Y op X, and ~X op C to X op' ~C. + 2007-03-04 Zdenek Dvorak <dvorakz@suse.cz> * tree-ssa-address.c (create_mem_ref): Do not put an expression diff --git a/gcc/fold-const.c b/gcc/fold-const.c index c8e2f514c71..dab2647ee28 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -8921,16 +8921,23 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1) /* Fold ~X op ~Y as Y op X. */ if (TREE_CODE (arg0) == BIT_NOT_EXPR && TREE_CODE (arg1) == BIT_NOT_EXPR) - return fold_build2 (code, type, - TREE_OPERAND (arg1, 0), - TREE_OPERAND (arg0, 0)); + { + tree cmp_type = TREE_TYPE (TREE_OPERAND (arg0, 0)); + return fold_build2 (code, type, + fold_convert (cmp_type, TREE_OPERAND (arg1, 0)), + TREE_OPERAND (arg0, 0)); + } /* Fold ~X op C as X op' ~C, where op' is the swapped comparison. */ if (TREE_CODE (arg0) == BIT_NOT_EXPR && TREE_CODE (arg1) == INTEGER_CST) - return fold_build2 (swap_tree_comparison (code), type, - TREE_OPERAND (arg0, 0), - fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg1), arg1)); + { + tree cmp_type = TREE_TYPE (TREE_OPERAND (arg0, 0)); + return fold_build2 (swap_tree_comparison (code), type, + TREE_OPERAND (arg0, 0), + fold_build1 (BIT_NOT_EXPR, cmp_type, + fold_convert (cmp_type, arg1))); + } return NULL_TREE; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 13e84470614..d469c95e120 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-03-04 Roger Sayle <roger@eyesopen.com> + + PR middle-end/30744 + * gcc.dg/pr30744-1.c: New test case. + 2007-03-04 Tobias Burnus <burnus@net-b.de> * gfortran.dg/c_by_val.c: Use _Complex instead of a struct. diff --git a/gcc/testsuite/gcc.dg/pr30744-1.c b/gcc/testsuite/gcc.dg/pr30744-1.c new file mode 100644 index 00000000000..f0734db60f2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr30744-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef struct { + unsigned long unique; +} G; + +void r(G* n) +{ + unsigned long p; + if (((G *) ((void *)((~(unsigned long)(p))))) != ((void *)0)) { + ((G *) ((void *)((~(unsigned long)(p)))))->unique = n->unique; + } +} + |