re PR middle-end/30744 (ICE in compare_values, at tree-vrp.c:466)
authorRoger Sayle <roger@eyesopen.com>
Sun, 4 Mar 2007 19:03:13 +0000 (19:03 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Sun, 4 Mar 2007 19:03:13 +0000 (19:03 +0000)
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.

From-SVN: r122531

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr30744-1.c [new file with mode: 0644]

index aaf8321174e435e2bb2ec4ff2335cd3c5b5e65b4..2646f347f16469c9892601b367e6277c6559a8af 100644 (file)
@@ -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
index c8e2f514c7181e754a079be899ed29e24f5c30b9..dab2647ee288cb26cc05de4bb4e9b322eaeb5d07 100644 (file)
@@ -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;
 }
index 13e8447061416d26a999e19c047b752e06a794ec..d469c95e120ff7b0f44314a654c990fe4e097d60 100644 (file)
@@ -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 (file)
index 0000000..f0734db
--- /dev/null
@@ -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;
+  }
+}
+