OSDN Git Service
(root)
/
pf3gnuchains
/
gcc-fork.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
c8a997f
)
(expand_builtin, case BUILT_IN_AGGREGATE_INCOMING_ADDRESS): New case.
author
kenner
<kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 2 Aug 1997 17:17:17 +0000
(17:17 +0000)
committer
kenner
<kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 2 Aug 1997 17:17:17 +0000
(17:17 +0000)
(expand_assignment, expand_expr, emit_push_insn, store_expr):
Insert calls to chkr_check_addr, chkr_set_right, and chkr_copy_bitmap
when -fcheck-memory-usage.
(get_push_address, get_memory_usage_from_modifier): New functions.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@14611
138bc75d
-0d04-0410-961f-
82ee72b054a4
gcc/expr.c
patch
|
blob
|
history
diff --git
a/gcc/expr.c
b/gcc/expr.c
index
9f5ad57
..
6937437
100644
(file)
--- a/
gcc/expr.c
+++ b/
gcc/expr.c
@@
-147,6
+147,7
@@
struct clear_by_pieces
as well as depth of arithmetic stack. (Notice that variables are
stored on the machine's stack, not the arithmetic stack.) */
as well as depth of arithmetic stack. (Notice that variables are
stored on the machine's stack, not the arithmetic stack.) */
+static rtx get_push_address PROTO ((int));
extern int local_vars_size;
extern int stack_depth;
extern int max_stack_depth;
extern int local_vars_size;
extern int stack_depth;
extern int max_stack_depth;
@@
-2368,6
+2369,25
@@
gen_push_operand ()
return gen_rtx (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
}
return gen_rtx (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
}
+/* Return an rtx for the address of the beginning of a as-if-it-was-pushed
+ block of SIZE bytes. */
+
+static rtx
+get_push_address (size)
+ int size;
+{
+ register rtx temp;
+
+ if (STACK_PUSH_CODE == POST_DEC)
+ temp = gen_rtx (PLUS, Pmode, stack_pointer_rtx, GEN_INT (size));
+ else if (STACK_PUSH_CODE == POST_INC)
+ temp = gen_rtx (MINUS, Pmode, stack_pointer_rtx, GEN_INT (size));
+ else
+ temp = stack_pointer_rtx;
+
+ return force_operand (temp, NULL_RTX);
+}
+
/* Generate code to push X onto the stack, assuming it has mode MODE and
type TYPE.
MODE is redundant except when X is a CONST_INT (since they don't
/* Generate code to push X onto the stack, assuming it has mode MODE and
type TYPE.
MODE is redundant except when X is a CONST_INT (since they don't
@@
-2487,6
+2507,25
@@
emit_push_insn (x, mode, type, size, align, partial, reg, extra,
move_by_pieces (gen_rtx (MEM, BLKmode, gen_push_operand ()), xinner,
INTVAL (size) - used, align);
move_by_pieces (gen_rtx (MEM, BLKmode, gen_push_operand ()), xinner,
INTVAL (size) - used, align);
+
+ if (flag_check_memory_usage)
+ {
+ rtx temp;
+
+ temp = get_push_address (INTVAL(size) - used);
+ if (GET_CODE (x) == MEM && AGGREGATE_TYPE_P (type))
+ emit_library_call (chkr_copy_bitmap_libfunc, 1, VOIDmode, 3,
+ temp, ptr_mode,
+ XEXP (xinner, 0), ptr_mode,
+ GEN_INT (INTVAL(size) - used),
+ TYPE_MODE (sizetype));
+ else
+ emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
+ temp, ptr_mode,
+ GEN_INT (INTVAL(size) - used),
+ TYPE_MODE (sizetype),
+ GEN_INT (MEMORY_USE_RW), QImode);
+ }
}
else
#endif /* PUSH_ROUNDING */
}
else
#endif /* PUSH_ROUNDING */
@@
-2522,6
+2561,22
@@
emit_push_insn (x, mode, type, size, align, partial, reg, extra,
plus_constant (gen_rtx (PLUS, Pmode,
args_addr, args_so_far),
skip));
plus_constant (gen_rtx (PLUS, Pmode,
args_addr, args_so_far),
skip));
+ if (flag_check_memory_usage)
+ {
+ rtx target;
+
+ target = copy_to_reg (temp);
+ if (GET_CODE (x) == MEM && AGGREGATE_TYPE_P (type))
+ emit_library_call (chkr_copy_bitmap_libfunc, 1, VOIDmode, 3,
+ target, ptr_mode,
+ XEXP (xinner, 0), ptr_mode,
+ size, TYPE_MODE (sizetype));
+ else
+ emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
+ target, ptr_mode,
+ size, TYPE_MODE (sizetype),
+ GEN_INT (MEMORY_USE_RW), QImode);
+ }
/* TEMP is the address of the block. Copy the data there. */
if (GET_CODE (size) == CONST_INT
/* TEMP is the address of the block. Copy the data there. */
if (GET_CODE (size) == CONST_INT
@@
-2687,6
+2742,7
@@
emit_push_insn (x, mode, type, size, align, partial, reg, extra,
else
{
rtx addr;
else
{
rtx addr;
+ rtx target = NULL_RTX;
/* Push padding now if padding above and stack grows down,
or if padding below and stack grows up.
/* Push padding now if padding above and stack grows down,
or if padding below and stack grows up.
@@
-2700,15
+2756,38
@@
emit_push_insn (x, mode, type, size, align, partial, reg, extra,
addr = gen_push_operand ();
else
#endif
addr = gen_push_operand ();
else
#endif
- if (GET_CODE (args_so_far) == CONST_INT)
- addr
- = memory_address (mode,
- plus_constant (args_addr, INTVAL (args_so_far)));
- else
- addr = memory_address (mode, gen_rtx (PLUS, Pmode, args_addr,
- args_so_far));
+ {
+ if (GET_CODE (args_so_far) == CONST_INT)
+ addr
+ = memory_address (mode,
+ plus_constant (args_addr,
+ INTVAL (args_so_far)));
+ else
+ addr = memory_address (mode, gen_rtx (PLUS, Pmode, args_addr,
+ args_so_far));
+ target = addr;
+ }
emit_move_insn (gen_rtx (MEM, mode, addr), x);
emit_move_insn (gen_rtx (MEM, mode, addr), x);
+
+ if (flag_check_memory_usage)
+ {
+ if (target == 0)
+ target = get_push_address (GET_MODE_SIZE (mode));
+
+ if (GET_CODE (x) == MEM && AGGREGATE_TYPE_P (type))
+ emit_library_call (chkr_copy_bitmap_libfunc, 1, VOIDmode, 3,
+ target, ptr_mode,
+ XEXP (x, 0), ptr_mode,
+ GEN_INT (GET_MODE_SIZE (mode)),
+ TYPE_MODE (sizetype));
+ else
+ emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
+ target, ptr_mode,
+ GEN_INT (GET_MODE_SIZE (mode)),
+ TYPE_MODE (sizetype),
+ GEN_INT (MEMORY_USE_RW), QImode);
+ }
}
ret:
}
ret:
@@
-2801,7
+2880,7
@@
expand_assignment (to, from, want_value, suggest_reg)
if (mode1 == VOIDmode && want_value)
tem = stabilize_reference (tem);
if (mode1 == VOIDmode && want_value)
tem = stabilize_reference (tem);
- to_rtx = expand_expr (tem, NULL_RTX, VOIDmode,
0
);
+ to_rtx = expand_expr (tem, NULL_RTX, VOIDmode,
EXPAND_MEMORY_USE_DONT
);
if (offset != 0)
{
rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
if (offset != 0)
{
rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
@@
-2832,6
+2911,31
@@
expand_assignment (to, from, want_value, suggest_reg)
#endif
}
#endif
}
+ /* Check the access. */
+ if (flag_check_memory_usage && GET_CODE (to_rtx) == MEM)
+ {
+ rtx to_addr;
+ int size;
+ int best_mode_size;
+ enum machine_mode best_mode;
+
+ best_mode = get_best_mode (bitsize, bitpos,
+ TYPE_ALIGN (TREE_TYPE (tem)),
+ mode1, volatilep);
+ if (best_mode == VOIDmode)
+ best_mode = QImode;
+
+ best_mode_size = GET_MODE_BITSIZE (best_mode);
+ to_addr = plus_constant (XEXP (to_rtx, 0), (bitpos / BITS_PER_UNIT));
+ size = CEIL ((bitpos % best_mode_size) + bitsize, best_mode_size);
+ size *= GET_MODE_SIZE (best_mode);
+
+ /* Check the access right of the pointer. */
+ emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3, to_addr,
+ ptr_mode, GEN_INT (size), TYPE_MODE (sizetype),
+ GEN_INT (MEMORY_USE_WO), QImode);
+ }
+
result = store_field (to_rtx, bitsize, bitpos, mode1, from,
(want_value
/* Spurious cast makes HPUX compiler happy. */
result = store_field (to_rtx, bitsize, bitpos, mode1, from,
(want_value
/* Spurious cast makes HPUX compiler happy. */
@@
-2873,7
+2977,7
@@
expand_assignment (to, from, want_value, suggest_reg)
push_temp_slots ();
value = expand_expr (from, NULL_RTX, VOIDmode, 0);
if (to_rtx == 0)
push_temp_slots ();
value = expand_expr (from, NULL_RTX, VOIDmode, 0);
if (to_rtx == 0)
- to_rtx = expand_expr (to, NULL_RTX, VOIDmode,
0
);
+ to_rtx = expand_expr (to, NULL_RTX, VOIDmode,
EXPAND_MEMORY_USE_WO
);
/* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
/* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
@@
-2894,7
+2998,7
@@
expand_assignment (to, from, want_value, suggest_reg)
Don't re-expand if it was expanded already (in COMPONENT_REF case). */
if (to_rtx == 0)
Don't re-expand if it was expanded already (in COMPONENT_REF case). */
if (to_rtx == 0)
- to_rtx = expand_expr (to, NULL_RTX, VOIDmode,
0
);
+ to_rtx = expand_expr (to, NULL_RTX, VOIDmode,
EXPAND_MEMORY_USE_WO
);
/* Don't move directly into a return register. */
if (TREE_CODE (to) == RESULT_DECL && GET_CODE (to_rtx) == REG)
/* Don't move directly into a return register. */
if (TREE_CODE (to) == RESULT_DECL && GET_CODE (to_rtx) == REG)
@@
-2921,7
+3025,17
@@
expand_assignment (to, from, want_value, suggest_reg)
push_temp_slots ();
size = expr_size (from);
push_temp_slots ();
size = expr_size (from);
- from_rtx = expand_expr (from, NULL_RTX, VOIDmode, 0);
+ from_rtx = expand_expr (from, NULL_RTX, VOIDmode,
+ EXPAND_MEMORY_USE_DONT);
+
+ /* Copy the rights of the bitmap. */
+ if (flag_check_memory_usage)
+ emit_library_call (chkr_copy_bitmap_libfunc, 1, VOIDmode, 3,
+ XEXP (to_rtx, 0), ptr_mode,
+ XEXP (from_rtx, 0), ptr_mode,
+ convert_to_mode (TYPE_MODE (sizetype),
+ size, TREE_UNSIGNED (sizetype)),
+ TYPE_MODE (sizetype));
#ifdef TARGET_MEM_FUNCTIONS
emit_library_call (memcpy_libfunc, 0,
#ifdef TARGET_MEM_FUNCTIONS
emit_library_call (memcpy_libfunc, 0,
@@
-3137,6
+3251,22
@@
store_expr (exp, target, want_value)
temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
temp, TREE_UNSIGNED (TREE_TYPE (exp)));
temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
temp, TREE_UNSIGNED (TREE_TYPE (exp)));
+ if (flag_check_memory_usage
+ && GET_CODE (target) == MEM
+ && AGGREGATE_TYPE_P (TREE_TYPE (exp)))
+ {
+ if (GET_CODE (temp) == MEM)
+ emit_library_call (chkr_copy_bitmap_libfunc, 1, VOIDmode, 3,
+ XEXP (target, 0), ptr_mode,
+ XEXP (temp, 0), ptr_mode,
+ expr_size (exp), TYPE_MODE (sizetype));
+ else
+ emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3,
+ XEXP (target, 0), ptr_mode,
+ expr_size (exp), TYPE_MODE (sizetype),
+ GEN_INT (MEMORY_USE_WO), QImode);
+ }
+
/* If value was not generated in the target, store it there.
Convert the value to TARGET's type first if nec. */
/* If value was not generated in the target, store it there.
Convert the value to TARGET's type first if nec. */
@@
-3220,6
+3350,12
@@
store_expr (exp, target, want_value)
if (size != const0_rtx)
{
if (size != const0_rtx)
{
+ /* Be sure we can write on ADDR. */
+ if (flag_check_memory_usage)
+ emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3,
+ addr, ptr_mode,
+ size, TYPE_MODE (sizetype),
+ GEN_INT (MEMORY_USE_WO), QImode);
#ifdef TARGET_MEM_FUNCTIONS
emit_library_call (memset_libfunc, 0, VOIDmode, 3,
addr, ptr_mode,
#ifdef TARGET_MEM_FUNCTIONS
emit_library_call (memset_libfunc, 0, VOIDmode, 3,
addr, ptr_mode,
@@
-4260,6
+4396,33
@@
get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
*palignment = alignment / BITS_PER_UNIT;
return exp;
}
*palignment = alignment / BITS_PER_UNIT;
return exp;
}
+
+/* Subroutine of expand_exp: compute memory_usage from modifier. */
+static enum memory_use_mode
+get_memory_usage_from_modifier (modifier)
+ enum expand_modifier modifier;
+{
+ switch (modifier)
+ {
+ case EXPAND_NORMAL:
+ return MEMORY_USE_RO;
+ break;
+ case EXPAND_MEMORY_USE_WO:
+ return MEMORY_USE_WO;
+ break;
+ case EXPAND_MEMORY_USE_RW:
+ return MEMORY_USE_RW;
+ break;
+ case EXPAND_INITIALIZER:
+ case EXPAND_MEMORY_USE_DONT:
+ case EXPAND_SUM:
+ case EXPAND_CONST_ADDRESS:
+ return MEMORY_USE_DONT;
+ case EXPAND_MEMORY_USE_BAD:
+ default:
+ abort ();
+ }
+}
\f
/* Given an rtx VALUE that may contain additions and multiplications,
return an equivalent value that just refers to a register or memory.
\f
/* Given an rtx VALUE that may contain additions and multiplications,
return an equivalent value that just refers to a register or memory.
@@
-4656,7
+4819,15
@@
expand_expr (exp, target, tmode, modifier)
|| code == COND_EXPR)
&& TREE_CODE (type) == VOID_TYPE));
tree context;
|| code == COND_EXPR)
&& TREE_CODE (type) == VOID_TYPE));
tree context;
+ /* Used by check-memory-usage to make modifier read only. */
+ enum expand_modifier ro_modifier;
+ /* Make a read-only version of the modifier. */
+ if (modifier == EXPAND_NORMAL || modifier == EXPAND_SUM
+ || modifier == EXPAND_CONST_ADDRESS || modifier == EXPAND_INITIALIZER)
+ ro_modifier = modifier;
+ else
+ ro_modifier = EXPAND_NORMAL;
if (output_bytecode && modifier != EXPAND_INITIALIZER)
{
if (output_bytecode && modifier != EXPAND_INITIALIZER)
{
@@
-4689,7
+4860,7
@@
expand_expr (exp, target, tmode, modifier)
&& TREE_CODE (exp) != FUNCTION_DECL
&& mode != VOIDmode && mode != BLKmode)
{
&& TREE_CODE (exp) != FUNCTION_DECL
&& mode != VOIDmode && mode != BLKmode)
{
- temp = expand_expr (exp, NULL_RTX, VOIDmode, modifier);
+ temp = expand_expr (exp, NULL_RTX, VOIDmode,
ro_
modifier);
if (GET_CODE (temp) == MEM)
temp = copy_to_reg (temp);
return const0_rtx;
if (GET_CODE (temp) == MEM)
temp = copy_to_reg (temp);
return const0_rtx;
@@
-4697,12
+4868,12
@@
expand_expr (exp, target, tmode, modifier)
if (TREE_CODE_CLASS (code) == '1')
return expand_expr (TREE_OPERAND (exp, 0), const0_rtx,
if (TREE_CODE_CLASS (code) == '1')
return expand_expr (TREE_OPERAND (exp, 0), const0_rtx,
- VOIDmode, modifier);
+ VOIDmode,
ro_
modifier);
else if (TREE_CODE_CLASS (code) == '2'
|| TREE_CODE_CLASS (code) == '<')
{
else if (TREE_CODE_CLASS (code) == '2'
|| TREE_CODE_CLASS (code) == '<')
{
- expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, modifier);
- expand_expr (TREE_OPERAND (exp, 1), const0_rtx, VOIDmode, modifier);
+ expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
ro_
modifier);
+ expand_expr (TREE_OPERAND (exp, 1), const0_rtx, VOIDmode,
ro_
modifier);
return const0_rtx;
}
else if ((code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
return const0_rtx;
}
else if ((code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
@@
-4710,7
+4881,7
@@
expand_expr (exp, target, tmode, modifier)
/* If the second operand has no side effects, just evaluate
the first. */
return expand_expr (TREE_OPERAND (exp, 0), const0_rtx,
/* If the second operand has no side effects, just evaluate
the first. */
return expand_expr (TREE_OPERAND (exp, 0), const0_rtx,
- VOIDmode, modifier);
+ VOIDmode,
ro_
modifier);
target = 0;
}
target = 0;
}
@@
-4776,6
+4947,26
@@
expand_expr (exp, target, tmode, modifier)
pop_obstacks ();
}
pop_obstacks ();
}
+ /* Only check automatic variables. Currently, function arguments are
+ not checked (this can be done at compile-time with prototypes).
+ Aggregates are not checked. */
+ if (flag_check_memory_usage && code == VAR_DECL
+ && GET_CODE (DECL_RTL (exp)) == MEM
+ && DECL_CONTEXT (exp) != NULL_TREE
+ && ! TREE_STATIC (exp)
+ && ! AGGREGATE_TYPE_P (TREE_TYPE (exp)))
+ {
+ enum memory_use_mode memory_usage;
+ memory_usage = get_memory_usage_from_modifier (modifier);
+
+ if (memory_usage != MEMORY_USE_DONT)
+ emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3,
+ XEXP (DECL_RTL (exp), 0), ptr_mode,
+ GEN_INT (int_size_in_bytes (type)),
+ TYPE_MODE (sizetype),
+ GEN_INT (memory_usage), QImode);
+ }
+
/* ... fall through ... */
case FUNCTION_DECL:
/* ... fall through ... */
case FUNCTION_DECL:
@@
-4889,7
+5080,8
@@
expand_expr (exp, target, tmode, modifier)
mode);
case CONST_DECL:
mode);
case CONST_DECL:
- return expand_expr (DECL_INITIAL (exp), target, VOIDmode, 0);
+ return expand_expr (DECL_INITIAL (exp), target, VOIDmode,
+ EXPAND_MEMORY_USE_BAD);
case REAL_CST:
/* If optimized, generate immediate CONST_DOUBLE
case REAL_CST:
/* If optimized, generate immediate CONST_DOUBLE
@@
-4982,7
+5174,8
@@
expand_expr (exp, target, tmode, modifier)
}
if (temp == const0_rtx)
}
if (temp == const0_rtx)
- expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
+ expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
+ EXPAND_MEMORY_USE_BAD);
else
store_expr (TREE_OPERAND (exp, 0), temp, 0);
}
else
store_expr (TREE_OPERAND (exp, 0), temp, 0);
}
@@
-5053,7
+5246,7
@@
expand_expr (exp, target, tmode, modifier)
In that case, we want to translate it using subsequent
entries. */
placeholder_list = TREE_CHAIN (placeholder_list);
In that case, we want to translate it using subsequent
entries. */
placeholder_list = TREE_CHAIN (placeholder_list);
- temp = expand_expr (object, original_target, tmode, modifier);
+ temp = expand_expr (object, original_target, tmode,
ro_
modifier);
placeholder_list = old_list;
return temp;
}
placeholder_list = old_list;
return temp;
}
@@
-5068,7
+5261,7
@@
expand_expr (exp, target, tmode, modifier)
placeholder_list = tree_cons (TREE_OPERAND (exp, 1), NULL_TREE,
placeholder_list);
target = expand_expr (TREE_OPERAND (exp, 0), original_target,
placeholder_list = tree_cons (TREE_OPERAND (exp, 1), NULL_TREE,
placeholder_list);
target = expand_expr (TREE_OPERAND (exp, 0), original_target,
- tmode, modifier);
+ tmode,
ro_
modifier);
placeholder_list = TREE_CHAIN (placeholder_list);
return target;
placeholder_list = TREE_CHAIN (placeholder_list);
return target;
@@
-5112,7
+5305,7
@@
expand_expr (exp, target, tmode, modifier)
vars = TREE_CHAIN (vars);
}
vars = TREE_CHAIN (vars);
}
- temp = expand_expr (TREE_OPERAND (exp, 1), target, tmode, modifier);
+ temp = expand_expr (TREE_OPERAND (exp, 1), target, tmode,
ro_
modifier);
expand_end_bindings (TREE_OPERAND (exp, 0), 0, 0);
expand_end_bindings (TREE_OPERAND (exp, 0), 0, 0);
@@
-5138,7
+5331,8
@@
expand_expr (exp, target, tmode, modifier)
{
tree elt;
for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
{
tree elt;
for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
- expand_expr (TREE_VALUE (elt), const0_rtx, VOIDmode, 0);
+ expand_expr (TREE_VALUE (elt), const0_rtx, VOIDmode,
+ EXPAND_MEMORY_USE_BAD);
return const0_rtx;
}
return const0_rtx;
}
@@
-5207,6
+5401,19
@@
expand_expr (exp, target, tmode, modifier)
op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
op0 = memory_address (mode, op0);
op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
op0 = memory_address (mode, op0);
+ if (flag_check_memory_usage && !AGGREGATE_TYPE_P (TREE_TYPE (exp)))
+ {
+ enum memory_use_mode memory_usage;
+ memory_usage = get_memory_usage_from_modifier (modifier);
+
+ if (memory_usage != MEMORY_USE_DONT)
+ emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3,
+ op0, ptr_mode,
+ GEN_INT (int_size_in_bytes (type)),
+ TYPE_MODE (sizetype),
+ GEN_INT (memory_usage), QImode);
+ }
+
temp = gen_rtx (MEM, mode, op0);
/* If address was computed by addition,
mark this as an element of an aggregate. */
temp = gen_rtx (MEM, mode, op0);
/* If address was computed by addition,
mark this as an element of an aggregate. */
@@
-5286,7
+5493,7
@@
expand_expr (exp, target, tmode, modifier)
elem = TREE_CHAIN (elem);
if (elem)
return expand_expr (fold (TREE_VALUE (elem)), target,
elem = TREE_CHAIN (elem);
if (elem)
return expand_expr (fold (TREE_VALUE (elem)), target,
- tmode, modifier);
+ tmode,
ro_
modifier);
}
}
}
}
@@
-5309,7
+5516,7
@@
expand_expr (exp, target, tmode, modifier)
elem = TREE_CHAIN (elem);
if (elem)
return expand_expr (fold (TREE_VALUE (elem)), target,
elem = TREE_CHAIN (elem);
if (elem)
return expand_expr (fold (TREE_VALUE (elem)), target,
- tmode, modifier);
+ tmode,
ro_
modifier);
}
else if (TREE_CODE (init) == STRING_CST
&& TREE_INT_CST_HIGH (index) == 0
}
else if (TREE_CODE (init) == STRING_CST
&& TREE_INT_CST_HIGH (index) == 0
@@
-5438,6
+5645,29
@@
expand_expr (exp, target, tmode, modifier)
MEM_VOLATILE_P (op0) = 1;
}
MEM_VOLATILE_P (op0) = 1;
}
+ /* Check the access. */
+ if (flag_check_memory_usage && GET_CODE (op0) == MEM)
+ {
+ enum memory_use_mode memory_usage;
+ memory_usage = get_memory_usage_from_modifier (modifier);
+
+ if (memory_usage != MEMORY_USE_DONT)
+ {
+ rtx to;
+ int size;
+
+ to = plus_constant (XEXP (op0, 0), (bitpos / BITS_PER_UNIT));
+ size = (bitpos % BITS_PER_UNIT) + bitsize + BITS_PER_UNIT - 1;
+
+ /* Check the access right of the pointer. */
+ emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3,
+ to, ptr_mode,
+ GEN_INT (size / BITS_PER_UNIT),
+ TYPE_MODE (sizetype),
+ GEN_INT (memory_usage), QImode);
+ }
+ }
+
/* In cases where an aligned union has an unaligned object
as a field, we might be extracting a BLKmode value from
an integer-mode (e.g., SImode) object. Handle this case
/* In cases where an aligned union has an unaligned object
as a field, we might be extracting a BLKmode value from
an integer-mode (e.g., SImode) object. Handle this case
@@
-5671,7
+5901,7
@@
expand_expr (exp, target, tmode, modifier)
if (RTL_EXPR_RTL (exp) == 0)
{
RTL_EXPR_RTL (exp)
if (RTL_EXPR_RTL (exp) == 0)
{
RTL_EXPR_RTL (exp)
- = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
+ = expand_expr (TREE_OPERAND (exp, 0), target, tmode,
ro_
modifier);
expand_decl_cleanup (NULL_TREE, TREE_OPERAND (exp, 2));
/* That's it for this cleanup. */
expand_decl_cleanup (NULL_TREE, TREE_OPERAND (exp, 2));
/* That's it for this cleanup. */
@@
-5688,7
+5918,7
@@
expand_expr (exp, target, tmode, modifier)
target_temp_slot_level = temp_slot_level;
target_temp_slot_level = temp_slot_level;
- op0 = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
+ op0 = expand_expr (TREE_OPERAND (exp, 0), target, tmode,
ro_
modifier);
/* If we're going to use this value, load it up now. */
if (! ignore)
op0 = force_not_mem (op0);
/* If we're going to use this value, load it up now. */
if (! ignore)
op0 = force_not_mem (op0);
@@
-5748,7
+5978,7
@@
expand_expr (exp, target, tmode, modifier)
if (mode == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
{
op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode,
if (mode == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
{
op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode,
- modifier);
+
ro_
modifier);
/* If the signedness of the conversion differs and OP0 is
a promoted SUBREG, clear that indication since we now
/* If the signedness of the conversion differs and OP0 is
a promoted SUBREG, clear that indication since we now
@@
-5870,8
+6100,8
@@
expand_expr (exp, target, tmode, modifier)
if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1)))
subtarget = 0;
if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1)))
subtarget = 0;
- op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier);
- op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, modifier);
+ op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode,
ro_
modifier);
+ op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode,
ro_
modifier);
both_summands:
/* Make sure any term that's a sum with a constant comes last. */
both_summands:
/* Make sure any term that's a sum with a constant comes last. */
@@
-5931,9
+6161,9
@@
expand_expr (exp, target, tmode, modifier)
&& really_constant_p (TREE_OPERAND (exp, 1)))
{
rtx op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX,
&& really_constant_p (TREE_OPERAND (exp, 1)))
{
rtx op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX,
- VOIDmode, modifier);
+ VOIDmode,
ro_
modifier);
rtx op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
rtx op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
- VOIDmode, modifier);
+ VOIDmode,
ro_
modifier);
/* If the last operand is a CONST_INT, use plus_constant of
the negated constant. Else make the MINUS. */
/* If the last operand is a CONST_INT, use plus_constant of
the negated constant. Else make the MINUS. */
@@
-5961,7
+6191,7
@@
expand_expr (exp, target, tmode, modifier)
return expand_expr (convert (type,
build (PLUS_EXPR, newtype,
newop0, newneg)),
return expand_expr (convert (type,
build (PLUS_EXPR, newtype,
newop0, newneg)),
- target, tmode, modifier);
+ target, tmode,
ro_
modifier);
}
else
{
}
else
{
@@
-5991,7
+6221,8
@@
expand_expr (exp, target, tmode, modifier)
&& TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
{
&& TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
{
- op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, EXPAND_SUM);
+ op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode,
+ EXPAND_SUM);
/* Apply distributive law if OP0 is x+c. */
if (GET_CODE (op0) == PLUS
/* Apply distributive law if OP0 is x+c. */
if (GET_CODE (op0) == PLUS
@@
-6415,11
+6646,11
@@
expand_expr (exp, target, tmode, modifier)
if (ignore)
{
expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
if (ignore)
{
expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
- modifier);
+
ro_
modifier);
return const0_rtx;
}
return const0_rtx;
}
- op0 = expand_expr (TREE_OPERAND (exp, 0), target, mode, modifier);
+ op0 = expand_expr (TREE_OPERAND (exp, 0), target, mode,
ro_
modifier);
if (GET_MODE (op0) == mode)
return op0;
if (GET_MODE (op0) == mode)
return op0;
@@
-8278,7
+8509,7
@@
expand_builtin (exp, target, subtarget, mode, ignore)
TREE_STATIC (result) = 1;
result = build (INDIRECT_REF, build_pointer_type (type), result);
TREE_CONSTANT (result) = 1;
TREE_STATIC (result) = 1;
result = build (INDIRECT_REF, build_pointer_type (type), result);
TREE_CONSTANT (result) = 1;
- return expand_expr (result, NULL_RTX, VOIDmode,
0
);
+ return expand_expr (result, NULL_RTX, VOIDmode,
EXPAND_MEMORY_USE_BAD
);
#endif
}
#endif
}
@@
-8422,6
+8653,16
@@
expand_builtin (exp, target, subtarget, mode, ignore)
return tem;
}
return tem;
}
+ /* Returns the address of the area where the structure is returned.
+ 0 otherwise. */
+ case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
+ if (arglist != 0
+ || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
+ || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
+ return const0_rtx;
+ else
+ return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
+
case BUILT_IN_ALLOCA:
if (arglist == 0
/* Arg could be non-integer if user redeclared this fcn wrong. */
case BUILT_IN_ALLOCA:
if (arglist == 0
/* Arg could be non-integer if user redeclared this fcn wrong. */
@@
-8477,7
+8718,7
@@
expand_builtin (exp, target, subtarget, mode, ignore)
/* If the length is known, just return it. */
if (len != 0)
/* If the length is known, just return it. */
if (len != 0)
- return expand_expr (len, target, mode,
0
);
+ return expand_expr (len, target, mode,
EXPAND_MEMORY_USE_BAD
);
/* If SRC is not a pointer type, don't do this operation inline. */
if (align == 0)
/* If SRC is not a pointer type, don't do this operation inline. */
if (align == 0)
@@
-9427,7
+9668,7
@@
expand_increment (exp, post, ignore)
and insns were generated in computing it. */
temp = get_last_insn ();
and insns were generated in computing it. */
temp = get_last_insn ();
- op0 = expand_expr (incremented, NULL_RTX, VOIDmode,
0
);
+ op0 = expand_expr (incremented, NULL_RTX, VOIDmode,
EXPAND_MEMORY_USE_RW
);
/* If OP0 is a SUBREG made for a promoted variable, we cannot increment
in place but instead must do sign- or zero-extension during assignment,
/* If OP0 is a SUBREG made for a promoted variable, we cannot increment
in place but instead must do sign- or zero-extension during assignment,
@@
-9458,7
+9699,8
@@
expand_increment (exp, post, ignore)
op0_is_copy = ((GET_CODE (op0) == SUBREG || GET_CODE (op0) == REG)
&& temp != get_last_insn ());
op0_is_copy = ((GET_CODE (op0) == SUBREG || GET_CODE (op0) == REG)
&& temp != get_last_insn ());
- op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
+ op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode,
+ EXPAND_MEMORY_USE_BAD);
/* Decide whether incrementing or decrementing. */
if (TREE_CODE (exp) == POSTDECREMENT_EXPR
/* Decide whether incrementing or decrementing. */
if (TREE_CODE (exp) == POSTDECREMENT_EXPR
@@
-9574,7
+9816,8
@@
expand_increment (exp, post, ignore)
temp = copy_rtx (value = op0);
/* Increment however we can. */
temp = copy_rtx (value = op0);
/* Increment however we can. */
- op1 = expand_binop (mode, this_optab, value, op1, op0,
+ op1 = expand_binop (mode, this_optab, value, op1,
+ flag_check_memory_usage ? NULL_RTX : op0,
TREE_UNSIGNED (TREE_TYPE (exp)), OPTAB_LIB_WIDEN);
/* Make sure the value is stored into OP0. */
if (op1 != op0)
TREE_UNSIGNED (TREE_TYPE (exp)), OPTAB_LIB_WIDEN);
/* Make sure the value is stored into OP0. */
if (op1 != op0)