aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>2001-10-27 21:30:46 +0000
committerRichard Kenner <kenner@gcc.gnu.org>2001-10-27 17:30:46 -0400
commit70072ed99ef3e03038eb3f753a74c2a679b16e31 (patch)
tree405578ab51ea1a9fff2cc1bea4d5779bbe7858df /gcc/expr.c
parent2bd989ca96bf548213f8ff6b6dbc1f327f005eaa (diff)
downloadgcc-70072ed99ef3e03038eb3f753a74c2a679b16e31.zip
gcc-70072ed99ef3e03038eb3f753a74c2a679b16e31.tar.gz
gcc-70072ed99ef3e03038eb3f753a74c2a679b16e31.tar.bz2
expr.c (stor_constructor_field): Always call adjust_address.
* expr.c (stor_constructor_field): Always call adjust_address. Copy TARGET before changing its alias set. (store_field): Likewise, for TO_RTX. (get_inner_reference): Stop at PLACEHOLDER_EXPR if can't find replacement. (safe_from_p, case ADDR_EXPR): Properly check for conflict. (find_placeholder): Return 0 if can't find object. (expand_expr, case PLACEHOLDER_EXPR): Abort if find_placeholder returns 0. From-SVN: r46571
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c66
1 files changed, 50 insertions, 16 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index d738d2d..cd90364 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -4472,13 +4472,12 @@ store_constructor_field (target, bitsize, bitpos,
generate unnecessary clear instructions anyways. */
&& (bitpos == 0 || GET_CODE (target) == MEM))
{
- if (bitpos != 0)
- target
- = adjust_address (target,
- GET_MODE (target) == BLKmode
- || 0 != (bitpos
- % GET_MODE_ALIGNMENT (GET_MODE (target)))
- ? BLKmode : VOIDmode, bitpos / BITS_PER_UNIT);
+ target
+ = adjust_address (target,
+ GET_MODE (target) == BLKmode
+ || 0 != (bitpos
+ % GET_MODE_ALIGNMENT (GET_MODE (target)))
+ ? BLKmode : VOIDmode, bitpos / BITS_PER_UNIT);
/* Show the alignment may no longer be what it was and update the alias
@@ -4488,7 +4487,10 @@ store_constructor_field (target, bitsize, bitpos,
if (GET_CODE (target) == MEM && ! MEM_KEEP_ALIAS_SET_P (target)
&& MEM_ALIAS_SET (target) != 0)
- set_mem_alias_set (target, alias_set);
+ {
+ target = copy_rtx (target);
+ set_mem_alias_set (target, alias_set);
+ }
store_constructor (exp, target, align, cleared, bitsize / BITS_PER_UNIT);
}
@@ -5354,7 +5356,10 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
MEM_SET_IN_STRUCT_P (to_rtx, 1);
if (!MEM_KEEP_ALIAS_SET_P (to_rtx) && MEM_ALIAS_SET (to_rtx) != 0)
- set_mem_alias_set (to_rtx, alias_set);
+ {
+ to_rtx = copy_rtx (to_rtx);
+ set_mem_alias_set (to_rtx, alias_set);
+ }
return store_expr (exp, to_rtx, value_mode != VOIDmode);
}
@@ -5502,7 +5507,16 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
else if (TREE_CODE (exp) == PLACEHOLDER_EXPR)
{
- exp = find_placeholder (exp, &placeholder_ptr);
+ tree new = find_placeholder (exp, &placeholder_ptr);
+
+ /* If we couldn't find the replacement, return the PLACEHOLDER_EXPR.
+ We might have been called from tree optimization where we
+ haven't set up an object yet. */
+ if (new == 0)
+ break;
+ else
+ exp = new;
+
continue;
}
else if (TREE_CODE (exp) != NON_LVALUE_EXPR
@@ -5778,9 +5792,26 @@ safe_from_p (x, exp, top_p)
switch (TREE_CODE (exp))
{
case ADDR_EXPR:
- return (staticp (TREE_OPERAND (exp, 0))
- || TREE_STATIC (exp)
- || safe_from_p (x, TREE_OPERAND (exp, 0), 0));
+ /* If the operand is static or we are static, we can't conflict.
+ Likewise if we don't conflict with the operand at all. */
+ if (staticp (TREE_OPERAND (exp, 0))
+ || TREE_STATIC (exp)
+ || safe_from_p (x, TREE_OPERAND (exp, 0), 0))
+ return 1;
+
+ /* Otherwise, the only way this can conflict is if we are taking
+ the address of a DECL a that address if part of X, which is
+ very rare. */
+ exp = TREE_OPERAND (exp, 0);
+ if (DECL_P (exp))
+ {
+ if (!DECL_RTL_SET_P (exp)
+ || GET_CODE (DECL_RTL (exp)) != MEM)
+ return 0;
+ else
+ exp_rtl = XEXP (DECL_RTL (exp), 0);
+ }
+ break;
case INDIRECT_REF:
if (GET_CODE (x) == MEM
@@ -6023,8 +6054,8 @@ highest_pow2_factor (exp)
/* Return an object on the placeholder list that matches EXP, a
PLACEHOLDER_EXPR. An object "matches" if it is of the type of the
PLACEHOLDER_EXPR or a pointer type to it. For further information, see
- tree.def. If no such object is found, abort. If PLIST is nonzero, it is
- a location which initially points to a starting location in the
+ tree.def. If no such object is found, return 0. If PLIST is nonzero, it
+ is a location which initially points to a starting location in the
placeholder list (zero means start of the list) and where a pointer into
the placeholder list at which the object is found is placed. */
@@ -6083,7 +6114,7 @@ find_placeholder (exp, plist)
}
}
- abort ();
+ return 0;
}
/* expand_expr: generate code for computing expression EXP.
@@ -6617,6 +6648,9 @@ expand_expr (exp, target, tmode, modifier)
tree placeholder_expr = 0;
exp = find_placeholder (exp, &placeholder_expr);
+ if (exp == 0)
+ abort ();
+
placeholder_list = TREE_CHAIN (placeholder_expr);
temp = expand_expr (exp, original_target, tmode, ro_modifier);
placeholder_list = old_list;