aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-ccp.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r--gcc/tree-ssa-ccp.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 0908d546f00..d0fcf3937a7 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -860,6 +860,10 @@ may_propagate_address_into_dereference (tree addr, tree deref)
gcc_assert (INDIRECT_REF_P (deref)
&& TREE_CODE (addr) == ADDR_EXPR);
+ /* Don't propagate if ADDR's operand has incomplete type. */
+ if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_OPERAND (addr, 0))))
+ return false;
+
/* If the address is invariant then we do not need to preserve restrict
qualifications. But we do need to preserve volatile qualifiers until
we can annotate the folded dereference itself properly. */
@@ -2720,10 +2724,19 @@ fold_gimple_assign (gimple_stmt_iterator *si)
case GIMPLE_BINARY_RHS:
/* Try to fold pointer addition. */
if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
- result = maybe_fold_stmt_addition (
- TREE_TYPE (gimple_assign_lhs (stmt)),
- gimple_assign_rhs1 (stmt),
- gimple_assign_rhs2 (stmt));
+ {
+ tree type = TREE_TYPE (gimple_assign_rhs1 (stmt));
+ if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
+ {
+ type = build_pointer_type (TREE_TYPE (TREE_TYPE (type)));
+ if (!useless_type_conversion_p
+ (TREE_TYPE (gimple_assign_lhs (stmt)), type))
+ type = TREE_TYPE (gimple_assign_rhs1 (stmt));
+ }
+ result = maybe_fold_stmt_addition (type,
+ gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt));
+ }
if (!result)
result = fold_binary (subcode,