summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/fold-const.c19
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr30744-1.c15
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;
+ }
+}
+
OpenPOWER on IntegriCloud