Commit 05e6ee93 by Michael Matz Committed by Michael Matz

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
parent ac05557c
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
......
......@@ -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
......
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
/* { 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment