From f876411dc99d011acd078c9f392a69c9493fa9a4 Mon Sep 17 00:00:00 2001 From: hp Date: Thu, 9 Sep 2004 20:31:11 +0000 Subject: [PATCH] PR target/17377 * gcc.c-torture/execute/pr17377.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@87250 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.c-torture/execute/pr17377.c | 59 +++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr17377.c diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 73a76d0..0e07e95 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-09-09 Hans-Peter Nilsson + + PR target/17377 + * gcc.c-torture/execute/pr17377.c: New test. + 2004-09-09 Joseph S. Myers PR c/8420 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr17377.c b/gcc/testsuite/gcc.c-torture/execute/pr17377.c new file mode 100644 index 0000000..0be6f0a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr17377.c @@ -0,0 +1,59 @@ +/* PR target/17377 + Bug in code emitted by "return" pattern on CRIS: missing pop of + forced return address on stack. */ +int calls = 0; + +void *f (int) __attribute__ ((__noinline__)); +void * +f (int i) +{ + /* The code does a little brittle song and dance to trig the "return" + pattern instead of the function epilogue. This must still be a + leaf function for the bug to be exposed. */ + + if (calls++ == 0) + return __builtin_return_address (0); + + switch (i) + { + case 1: + return f; + case 0: + return __builtin_return_address (0); + } + return 0; +} + +int x; + +void *y (int i) __attribute__ ((__noinline__)); +void * +y (int i) +{ + x = 0; + + /* This must not be a sibling call: the return address must appear + constant for different calls to this function. Postincrementing x + catches otherwise unidentified multiple returns (e.g. through the + return-address register and then this epilogue popping the address + stored on stack in "f"). */ + return (char *) f (i) + x++; +} + +int +main (void) +{ + void *v = y (4); + if (y (1) != f + /* Can't reasonably check the validity of the return address + above, but it's not that important: the test-case will probably + crash on the first call to f with the bug present, or it will + run wild including returning early (in y or here), so we also + try and check the number of calls. */ + || y (0) != v + || y (3) != 0 + || y (-1) != 0 + || calls != 5) + abort (); + exit (0); +} -- 2.7.4