re PR middle-end/35616 (Incorrect code while O2 compling)
PR middle-end/35616 * calls.c (expand_call): Check overlap of arguments with call address for sibcalls. * gcc.dg/pr35616.c: New test. From-SVN: r133348
This commit is contained in:
parent
ac05557cc7
commit
05e6ee933e
@ -1,3 +1,9 @@
|
||||
2008-03-19 Michael Matz <matz@suse.de>
|
||||
|
||||
PR middle-end/35616
|
||||
* calls.c (expand_call): Check overlap of arguments with call
|
||||
address for sibcalls.
|
||||
|
||||
2008-03-19 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
PR target/35496
|
||||
|
10
gcc/calls.c
10
gcc/calls.c
@ -2326,7 +2326,7 @@ expand_call (tree exp, rtx target, int ignore)
|
||||
int save_pending_stack_adjust = 0;
|
||||
int save_stack_pointer_delta = 0;
|
||||
rtx insns;
|
||||
rtx before_call, next_arg_reg;
|
||||
rtx before_call, next_arg_reg, after_args;
|
||||
|
||||
if (pass == 0)
|
||||
{
|
||||
@ -2756,6 +2756,7 @@ expand_call (tree exp, rtx target, int ignore)
|
||||
use_reg (&call_fusage, struct_value);
|
||||
}
|
||||
|
||||
after_args = get_last_insn ();
|
||||
funexp = prepare_call_address (funexp, static_chain_value,
|
||||
&call_fusage, reg_parm_seen, pass == 0);
|
||||
|
||||
@ -2790,6 +2791,13 @@ expand_call (tree exp, rtx target, int ignore)
|
||||
next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
|
||||
flags, & args_so_far);
|
||||
|
||||
/* If the call setup or the call itself overlaps with anything
|
||||
of the argument setup we probably clobbered our call address.
|
||||
In that case we can't do sibcalls. */
|
||||
if (pass == 0
|
||||
&& check_sibcall_argument_overlap (after_args, 0, 0))
|
||||
sibcall_failure = 1;
|
||||
|
||||
/* If a non-BLKmode value is returned at the most significant end
|
||||
of a register, shift the register right by the appropriate amount
|
||||
and update VALREG accordingly. BLKmode values are handled by the
|
||||
|
@ -1,3 +1,8 @@
|
||||
2008-03-19 Michael Matz <matz@suse.de>
|
||||
|
||||
PR middle-end/35616
|
||||
* gcc.dg/pr35616.c: New test.
|
||||
|
||||
2008-03-19 Daniel Franke <franke.daniel@gmail.com>
|
||||
|
||||
PR fortran/35152
|
||||
|
43
gcc/testsuite/gcc.dg/pr35616.c
Normal file
43
gcc/testsuite/gcc.dg/pr35616.c
Normal file
@ -0,0 +1,43 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-O2" } */
|
||||
typedef void (*listener_fun)(
|
||||
int a,
|
||||
int b,
|
||||
int c);
|
||||
|
||||
struct data_t
|
||||
{
|
||||
int a;
|
||||
|
||||
listener_fun listener;
|
||||
|
||||
int b;
|
||||
int c;
|
||||
int d;
|
||||
};
|
||||
|
||||
extern void abort(void);
|
||||
void function_calling_listener (struct data_t data);
|
||||
|
||||
void function_calling_listener (struct data_t data)
|
||||
{
|
||||
data.listener(data.a, data.c, data.d);
|
||||
}
|
||||
|
||||
void my_listener(int a, int b, int c)
|
||||
{
|
||||
if (a != 42 || b != 44 || c != 45)
|
||||
abort ();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
struct data_t d;
|
||||
d.a = 42;
|
||||
d.b = 43;
|
||||
d.c = 44;
|
||||
d.d = 45;
|
||||
d.listener = my_listener;
|
||||
function_calling_listener (d);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user