summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-ccp.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2008-03-17 14:34:21 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2008-03-17 14:34:21 +0000
commit0b4a6afcc4db5ef1f6a983363a5e72d09626a4c6 (patch)
tree953f8e21808467a87b2490c396b2f654c4d588ca /gcc/tree-ssa-ccp.c
parentb6d2ab40ae899bb9bda13f76c0962497aa91b42d (diff)
downloadgcc-0b4a6afcc4db5ef1f6a983363a5e72d09626a4c6.tar.gz
2008-03-17 Richard Guenther <rguenther@suse.de>
PR tree-optimization/19637 * fold-const.c (fold_unary): Remove restrictions of removing intermediate pointer-conversions (P2)(P1)P0. * tree-ssa-ccp.c (maybe_fold_stmt_addition): Recover from conversion to void pointer. (get_maxval_strlen): Handle addresses of the form &(*p)[0]. * g++.dg/tree-ssa/pr19637.C: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@133291 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r--gcc/tree-ssa-ccp.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index f087a8d8948..7e519264f7a 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -2105,6 +2105,12 @@ maybe_fold_stmt_addition (tree expr)
}
ptd_type = TREE_TYPE (ptr_type);
+ /* If we want a pointer to void, reconstruct the reference from the
+ array element type. A pointer to that can be trivially converted
+ to void *. This happens as we fold (void *)(ptr p+ off). */
+ if (VOID_TYPE_P (ptd_type)
+ && TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE)
+ ptd_type = TREE_TYPE (TREE_TYPE (op0));
/* At which point we can try some of the same things as for indirects. */
t = maybe_fold_offset_to_array_ref (op0, op1, ptd_type, true);
@@ -2292,6 +2298,17 @@ get_maxval_strlen (tree arg, tree *length, bitmap visited, int type)
if (TREE_CODE (arg) == COND_EXPR)
return get_maxval_strlen (COND_EXPR_THEN (arg), length, visited, type)
&& get_maxval_strlen (COND_EXPR_ELSE (arg), length, visited, type);
+ /* We can end up with &(*iftmp_1)[0] here as well, so handle it. */
+ else if (TREE_CODE (arg) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (arg, 0)) == ARRAY_REF
+ && integer_zerop (TREE_OPERAND (TREE_OPERAND (arg, 0), 1)))
+ {
+ tree aop0 = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
+ if (TREE_CODE (aop0) == INDIRECT_REF
+ && TREE_CODE (TREE_OPERAND (aop0, 0)) == SSA_NAME)
+ return get_maxval_strlen (TREE_OPERAND (aop0, 0),
+ length, visited, type);
+ }
if (type == 2)
{