re PR middle-end/27529 (Does not fold (char *)(size_t)char_ptr or (size_t)(char ...
authorRichard Guenther <rguenther@suse.de>
Thu, 11 May 2006 08:29:40 +0000 (08:29 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 11 May 2006 08:29:40 +0000 (08:29 +0000)
2006-05-11  Richard Guenther  <rguenther@suse.de>

PR middle-end/27529
* fold-const.c (fold_unary): Handle intermediate conversion
to a pointer type like intermediate conversion to an integer
type in folding of (T1)(T2)var to var.
Match the code to the comment in the final conversion for
(T1)(T2)var to (T1)var regarding to type precision.  Rather
than disallow T1 being of pointer type, assert that both T1
and var are of pointer type or not.  Make sure not to fall
over the frontends lazyness wrt array to pointer decay though.

* gcc.dg/tree-ssa/foldcast-1.c: New testcase.

From-SVN: r113692

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

index 35226d1350cf53fb88dd05769e71c357e5a05fbe..31f6974ad2405a0b3dfae843980d21471acc916d 100644 (file)
@@ -1,3 +1,15 @@
+2006-05-11  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/27529
+       * fold-const.c (fold_unary): Handle intermediate conversion
+       to a pointer type like intermediate conversion to an integer
+       type in folding of (T1)(T2)var to var.
+       Match the code to the comment in the final conversion for
+       (T1)(T2)var to (T1)var regarding to type precision.  Rather
+       than disallow T1 being of pointer type, assert that both T1
+       and var are of pointer type or not.  Make sure not to fall
+       over the frontends lazyness wrt array to pointer decay though.
+
 2006-05-10  Richard Earnshaw  <rearnsha@arm.com>
 
        * arm.c (arm_struct_value_rtx): Delete.
index 030bcb1c951306469072fa1d220dab43465decd1..ce689291eb6a0972dbe14966ec81254a72a78214 100644 (file)
@@ -7323,7 +7323,8 @@ fold_unary (enum tree_code code, tree type, tree op0)
             type via an object of identical or wider precision, neither
             conversion is needed.  */
          if (TYPE_MAIN_VARIANT (inside_type) == TYPE_MAIN_VARIANT (type)
-             && ((inter_int && final_int) || (inter_float && final_float))
+             && (((inter_int || inter_ptr) && final_int)
+                 || (inter_float && final_float))
              && inter_prec >= final_prec)
            return fold_build1 (code, type, TREE_OPERAND (op0, 0));
 
@@ -7362,10 +7363,13 @@ fold_unary (enum tree_code code, tree type, tree op0)
             - the initial type is a pointer type and the precisions of the
               intermediate and final types differ, or
             - the final type is a pointer type and the precisions of the
-              initial and intermediate types differ.  */
+              initial and intermediate types differ.
+            - the final type is a pointer type and the initial type not
+            - the initial type is a pointer to an array and the final type
+              not.  */
          if (! inside_float && ! inter_float && ! final_float
              && ! inside_vec && ! inter_vec && ! final_vec
-             && (inter_prec > inside_prec || inter_prec > final_prec)
+             && (inter_prec >= inside_prec || inter_prec >= final_prec)
              && ! (inside_int && inter_int
                    && inter_unsignedp != inside_unsignedp
                    && inter_prec < final_prec)
@@ -7375,7 +7379,10 @@ fold_unary (enum tree_code code, tree type, tree op0)
              && ! (final_ptr && inside_prec != inter_prec)
              && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
                    && TYPE_MODE (type) == TYPE_MODE (inter_type))
-             && ! final_ptr)
+             && final_ptr == inside_ptr
+             && ! (inside_ptr
+                   && TREE_CODE (TREE_TYPE (inside_type)) == ARRAY_TYPE
+                   && TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
            return fold_build1 (code, type, TREE_OPERAND (op0, 0));
        }
 
index 35fbf2dd7a3bdaa96b192e9ffacc7fc8a5745963..418c6718b0339cf9612feeba54308557a906b3ea 100644 (file)
@@ -1,3 +1,8 @@
+2006-05-11  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/27529
+       * gcc.dg/tree-ssa/foldcast-1.c: New testcase.
+
 2006-05-10  Janis Johnson  <janis187@us.ibm.com>
 
        * lib/target-supports-dg.exp (check-flags): New.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/foldcast-1.c b/gcc/testsuite/gcc.dg/tree-ssa/foldcast-1.c
new file mode 100644 (file)
index 0000000..a0626ea
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do "compile" } */
+/* { dg-options "-fdump-tree-original" } */
+
+typedef int ssize_t __attribute__((mode(pointer)));
+ssize_t foo (ssize_t x)
+{
+  return (ssize_t)(char *)x;
+}
+
+char *bar (char *x)
+{
+  return (char *)(ssize_t)x;
+}
+
+/* { dg-final { scan-tree-dump-times "return x;" 2 "original" } } */
+/* { dg-final { cleanup-tree-dump "original" } } */