diff options
author | Jakub Jelinek <jakub@redhat.com> | 2025-07-11 12:09:44 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2025-07-11 12:09:44 +0200 |
commit | 89b9372d61ccd45cb6c71518d62215917e3aaebc (patch) | |
tree | de5b0d854ff7418222eb8c591131938108c69467 /gcc/testsuite | |
parent | 5ca44dfb1389f4c6198283683547143e217f65ab (diff) | |
download | gcc-89b9372d61ccd45cb6c71518d62215917e3aaebc.zip gcc-89b9372d61ccd45cb6c71518d62215917e3aaebc.tar.gz gcc-89b9372d61ccd45cb6c71518d62215917e3aaebc.tar.bz2 |
ipa: Disallow signature changes in fun->has_musttail functions [PR121023]
As the following testcase shows e.g. on ia32, letting IPA opts change
signature of functions which have [[{gnu,clang}::musttail]] calls
can turn programs that would be compiled normally into something
that is rejected because the caller has fewer argument stack slots
than the function being tail called.
The following patch prevents signature changes for such functions.
It is perhaps too big hammer in some cases, but it might be hard
to try to figure out what signature changes are still acceptable and which
are not at IPA time.
2025-07-11 Jakub Jelinek <jakub@redhat.com>
Martin Jambor <mjambor@suse.cz>
PR ipa/121023
* ipa-fnsummary.cc (compute_fn_summary): Disallow signature changes
on cfun->has_musttail functions.
* c-c++-common/musttail32.c: New test.
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/c-c++-common/musttail32.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/gcc/testsuite/c-c++-common/musttail32.c b/gcc/testsuite/c-c++-common/musttail32.c new file mode 100644 index 0000000..f1b7052 --- /dev/null +++ b/gcc/testsuite/c-c++-common/musttail32.c @@ -0,0 +1,23 @@ +/* PR ipa/121023 */ +/* { dg-do compile { target musttail } } */ +/* { dg-options "-O2" } */ + +struct S { int a, b; }; + +[[gnu::noipa]] int +foo (struct S x, int y, int z) +{ + return x.a + y + z; +} + +[[gnu::noinline]] static int +bar (struct S x, int y, int z) +{ + [[gnu::musttail]] return foo ((struct S) { x.a, 0 }, y, 1); +} + +int +baz (int x) +{ + return bar ((struct S) { 1, 2 }, x, 2) + bar ((struct S) { 2, 3 }, x + 1, 2); +} |