* [patch] fix PR middle-end/35616, sibcall miscompilation
@ 2008-03-18 16:08 Michael Matz
2008-03-18 16:57 ` Richard Guenther
0 siblings, 1 reply; 2+ messages in thread
From: Michael Matz @ 2008-03-18 16:08 UTC (permalink / raw)
To: gcc-patches
Hi,
as seen in the bugreport expand_call fails to ensure that the call address
doesn't overlap with the arguments for sibcalls (it checks all
inter-argument overlap and disables sibcalls then, but if the arguments
don't overlap, but one of them overlaps the call address it's clobbered as
in the testcase).
Regstrapping in progress on i686 and x86_64. Okay for trunk if this
passes? What with 4.3?
Ciao,
Michael.
PR middle-end/35616
* calls.c (expand_call): Check overlap of arguments with call
address for sibcalls.
* gcc.dg/pr35616.c: New test.
Index: gcc/calls.c
===================================================================
--- gcc/calls.c (revision 133304)
+++ gcc/calls.c (working copy)
@@ -2326,7 +2326,7 @@ expand_call (tree exp, rtx target, int i
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 i
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 i
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
Index: gcc/testsuite/gcc.dg/pr35616.c
===================================================================
--- gcc/testsuite/gcc.dg/pr35616.c (revision 0)
+++ gcc/testsuite/gcc.dg/pr35616.c (revision 0)
@@ -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;
+}
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [patch] fix PR middle-end/35616, sibcall miscompilation
2008-03-18 16:08 [patch] fix PR middle-end/35616, sibcall miscompilation Michael Matz
@ 2008-03-18 16:57 ` Richard Guenther
0 siblings, 0 replies; 2+ messages in thread
From: Richard Guenther @ 2008-03-18 16:57 UTC (permalink / raw)
To: Michael Matz; +Cc: gcc-patches
On Tue, Mar 18, 2008 at 5:03 PM, Michael Matz <matz@suse.de> wrote:
> Hi,
>
> as seen in the bugreport expand_call fails to ensure that the call address
> doesn't overlap with the arguments for sibcalls (it checks all
> inter-argument overlap and disables sibcalls then, but if the arguments
> don't overlap, but one of them overlaps the call address it's clobbered as
> in the testcase).
>
> Regstrapping in progress on i686 and x86_64. Okay for trunk if this
> passes? What with 4.3?
Ok for trunk and all open branches.
Thanks,
Richard.
>
> Ciao,
> Michael.
> PR middle-end/35616
> * calls.c (expand_call): Check overlap of arguments with call
> address for sibcalls.
>
> * gcc.dg/pr35616.c: New test.
>
> Index: gcc/calls.c
> ===================================================================
> --- gcc/calls.c (revision 133304)
> +++ gcc/calls.c (working copy)
> @@ -2326,7 +2326,7 @@ expand_call (tree exp, rtx target, int i
> 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 i
> 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 i
> 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
> Index: gcc/testsuite/gcc.dg/pr35616.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/pr35616.c (revision 0)
> +++ gcc/testsuite/gcc.dg/pr35616.c (revision 0)
> @@ -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;
> +}
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2008-03-18 16:11 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-18 16:08 [patch] fix PR middle-end/35616, sibcall miscompilation Michael Matz
2008-03-18 16:57 ` Richard Guenther
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).