From: Hans-Peter Nilsson Date: Thu, 9 Sep 2004 20:31:11 +0000 (+0000) Subject: re PR target/17377 (cris.md bug in "return" pattern trigged by __builtin_return_address) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=da3107f38b72d49e39ca0386b2ecc94deed9bcce;p=gcc.git re PR target/17377 (cris.md bug in "return" pattern trigged by __builtin_return_address) PR target/17377 * gcc.c-torture/execute/pr17377.c: New test. From-SVN: r87250 --- diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 73a76d029af..0e07e956f82 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 00000000000..0be6f0a849e --- /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); +}