diff options
| -rw-r--r-- | gcc/ChangeLog | 12 | ||||
| -rw-r--r-- | gcc/fold-const.c | 15 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/foldcast-1.c | 16 |
4 files changed, 44 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 35226d1..31f6974 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 030bcb1..ce68929 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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)); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 35fbf2d..418c671 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..a0626ea --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/foldcast-1.c @@ -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" } } */ |
