diff options
Diffstat (limited to 'gcc/tree-ssa-ccp.c')
-rw-r--r-- | gcc/tree-ssa-ccp.c | 21 |
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, |