re PR middle-end/29683 (Arg split between stack/regs can cause stack corruption)

2007-03-01  Josh Conner  <jconner@apple.com>

	PR middle-end/29683
	* calls.c (compute_argument_addresses): Set stack and stack_slot
	for partial args, too.
	(store_one_arg): Use locate.size.constant for the size when
	generating a save_area.

2007-03-01  Josh Conner  <jconner@apple.com>

	PR middle-end/29683
	* gcc.dg/pr29683.c: New.

From-SVN: r120425
This commit is contained in:
Josh Conner 2007-01-04 01:37:15 +00:00 committed by Josh Conner
parent 4e8b35902b
commit 7816b87eb1
4 changed files with 94 additions and 8 deletions

View File

@ -1,3 +1,11 @@
2007-01-03 Josh Conner <jconner@apple.com>
PR middle-end/29683
* calls.c (compute_argument_addresses): Set stack and stack_slot
for partial args, too.
(store_one_arg): Use locate.size.constant for the size when
generating a save_area.
2007-01-03 Robert Kennedy <jimbob@google.com>
* tree-cfg.c (tree_merge_blocks): Release SSA_NAME phi results

View File

@ -1355,9 +1355,13 @@ compute_argument_addresses (struct arg_data *args, rtx argblock, int num_actuals
rtx slot_offset = ARGS_SIZE_RTX (args[i].locate.slot_offset);
rtx addr;
unsigned int align, boundary;
unsigned int units_on_stack = 0;
enum machine_mode partial_mode = VOIDmode;
/* Skip this parm if it will not be passed on the stack. */
if (! args[i].pass_on_stack && args[i].reg != 0)
if (! args[i].pass_on_stack
&& args[i].reg != 0
&& args[i].partial == 0)
continue;
if (GET_CODE (offset) == CONST_INT)
@ -1366,9 +1370,23 @@ compute_argument_addresses (struct arg_data *args, rtx argblock, int num_actuals
addr = gen_rtx_PLUS (Pmode, arg_reg, offset);
addr = plus_constant (addr, arg_offset);
args[i].stack = gen_rtx_MEM (args[i].mode, addr);
set_mem_attributes (args[i].stack,
TREE_TYPE (args[i].tree_value), 1);
if (args[i].partial != 0)
{
/* Only part of the parameter is being passed on the stack.
Generate a simple memory reference of the correct size. */
units_on_stack = args[i].locate.size.constant;
partial_mode = mode_for_size (units_on_stack * BITS_PER_UNIT,
MODE_INT, 1);
args[i].stack = gen_rtx_MEM (partial_mode, addr);
set_mem_size (args[i].stack, GEN_INT (units_on_stack));
}
else
{
args[i].stack = gen_rtx_MEM (args[i].mode, addr);
set_mem_attributes (args[i].stack,
TREE_TYPE (args[i].tree_value), 1);
}
align = BITS_PER_UNIT;
boundary = args[i].locate.boundary;
if (args[i].locate.where_pad != downward)
@ -1386,9 +1404,21 @@ compute_argument_addresses (struct arg_data *args, rtx argblock, int num_actuals
addr = gen_rtx_PLUS (Pmode, arg_reg, slot_offset);
addr = plus_constant (addr, arg_offset);
args[i].stack_slot = gen_rtx_MEM (args[i].mode, addr);
set_mem_attributes (args[i].stack_slot,
TREE_TYPE (args[i].tree_value), 1);
if (args[i].partial != 0)
{
/* Only part of the parameter is being passed on the stack.
Generate a simple memory reference of the correct size.
*/
args[i].stack_slot = gen_rtx_MEM (partial_mode, addr);
set_mem_size (args[i].stack_slot, GEN_INT (units_on_stack));
}
else
{
args[i].stack_slot = gen_rtx_MEM (args[i].mode, addr);
set_mem_attributes (args[i].stack_slot,
TREE_TYPE (args[i].tree_value), 1);
}
set_mem_align (args[i].stack_slot, args[i].locate.boundary);
/* Function incoming arguments may overlap with sibling call
@ -4056,7 +4086,7 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags,
arg->save_area = assign_temp (nt, 0, 1, 1);
preserve_temp_slots (arg->save_area);
emit_block_move (validize_mem (arg->save_area), stack_area,
expr_size (arg->tree_value),
GEN_INT (arg->locate.size.constant),
BLOCK_OP_CALL_PARM);
}
else

View File

@ -1,3 +1,8 @@
2007-01-03 Josh Conner <jconner@apple.com>
PR middle-end/29683
* gcc.dg/pr29683.c: New.
2007-01-03 Jakub Jelinek <jakub@redhat.com>
PR c++/28217

View File

@ -0,0 +1,43 @@
/* { dg-do run } */
/* { dg-options "-Os -fno-inline-functions" } */
void abort (void);
typedef struct {
int x[7];
} agg7;
typedef struct {
int mbr1;
int mbr2;
} agg2;
int expected = 31415;
agg7 filler;
int GetConst (agg7 filler, agg2 split)
{
return expected;
}
void VerifyValues (agg7 filler, int last_reg, int first_stack, int second_stack)
{
if (first_stack != 123 || second_stack != expected)
abort ();
}
void RunTest (agg2 a)
{
int result;
result = GetConst (filler, a);
VerifyValues (filler, 0, a.mbr1, result);
}
int main(void)
{
agg2 result = {123, 456};
RunTest (result);
return 0;
}