mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-28 22:34:03 +08:00
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:
parent
4e8b35902b
commit
7816b87eb1
@ -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
|
||||
|
46
gcc/calls.c
46
gcc/calls.c
@ -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
|
||||
|
@ -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
|
||||
|
43
gcc/testsuite/gcc.dg/pr29683.c
Normal file
43
gcc/testsuite/gcc.dg/pr29683.c
Normal 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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user