From f802f27b85e93c508d78f3ccf07488e837a1989d Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 29 Oct 2010 09:56:18 -0700 Subject: [PATCH] re PR rtl-optimization/46226 (asm goto may leave stack pointer invalid) PR rtl-opt/46226 * stmt.c (expand_asm_operands): Call do_pending_stack_adjust for asm goto. From-SVN: r166067 --- gcc/ChangeLog | 6 ++++++ gcc/stmt.c | 4 ++++ gcc/testsuite/gcc.dg/pr46226.c | 36 ++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr46226.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d207ffd57be..dc6d2313cce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-10-29 Richard Henderson + + PR rtl-opt/46226 + * stmt.c (expand_asm_operands): Call do_pending_stack_adjust + for asm goto. + 2010-10-29 Paul Koning * config/pdp11/pdp11.c (output_move_quad): Fix ICE for CPU diff --git a/gcc/stmt.c b/gcc/stmt.c index 9096d8385dd..c8f56f5470b 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -776,6 +776,10 @@ expand_asm_operands (tree string, tree outputs, tree inputs, /* Second pass evaluates arguments. */ + /* Make sure stack is consistent for asm goto. */ + if (nlabels > 0) + do_pending_stack_adjust (); + ninout = 0; for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) { diff --git a/gcc/testsuite/gcc.dg/pr46226.c b/gcc/testsuite/gcc.dg/pr46226.c new file mode 100644 index 00000000000..9934a4fbc79 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr46226.c @@ -0,0 +1,36 @@ +/* { dg-do run } */ +/* { dg-options "-Os -fomit-frame-pointer" } */ +/* { dg-options "-Os -fomit-frame-pointer -mno-accumulate-outgoing-args -fno-asynchronous-unwind-tables" { target { i?86-*-* x86_64-*-* } } } */ + +extern void abort(void); + +static void *p[2]; + +void __attribute__((noinline)) +g(int x, ...) +{ + asm volatile ("" : : "g"(x)); +} + +void __attribute__((noinline)) +f(int x) +{ + p[0] = __builtin_return_address (0); + if (x == 0) + g(0); + g(1, 2, 3, 4, 5, 6, 7); + + asm goto ("jmp %l0" : : : : label); + abort (); + + label: + p[1] = __builtin_return_address (0); +} + +int main() +{ + f(1); + if (p[0] != p[1]) + abort (); + return 0; +}