aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-inline.cc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-03-21 12:17:01 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2025-03-21 12:17:01 +0100
commit37ae2e055687a22974d7bcb9e618f258fa49ab1a (patch)
treefb7da6a776f583036214286f8c3335a4be1cfdcc /gcc/tree-inline.cc
parent778c28c70f8573f8256c810ff0d9e143ff75dec3 (diff)
downloadgcc-37ae2e055687a22974d7bcb9e618f258fa49ab1a.zip
gcc-37ae2e055687a22974d7bcb9e618f258fa49ab1a.tar.gz
gcc-37ae2e055687a22974d7bcb9e618f258fa49ab1a.tar.bz2
inliner: Silently drop musttail flag on calls during inlining unless the inlined routine was musttail called [PR119376]
As discussed in the PR, some packages fail to build because they use musttail attribute on calls in functions which we inline, and if they are inlined into a middle of the function, that results in an error because we have a musttail call in the middle of a function and so it can't be tail called there. Now, guess the primary intent of the musttail attribute is ensuring we don't get an extra stack frame in the backtrace. Inlining itself removes one extra stack frame from the backtrace as well (sure, not counting virtual backtraces in gdb), so I think erroring out on that is unnecessary. Except when we are inlining a musttail call which has musttail calls in it, in that case we are being asked to remove 2 stack frames from the backtrace, inlining removes one, so we need to keep musttail on the calls so that another stack frame is removed through a tail call. The following patch implements that, keeping previous behavior when id->call_stmt is NULL (i.e. when versioning/cloning etc.). 2025-03-21 Jakub Jelinek <jakub@redhat.com> PR ipa/119376 * tree-inline.cc (remap_gimple_stmt): Silently clear gimple_call_must_tail_p on inlined call stmts if id->call_stmt is a call without that flag set. * c-c++-common/musttail26.c: New test.
Diffstat (limited to 'gcc/tree-inline.cc')
-rw-r--r--gcc/tree-inline.cc9
1 files changed, 9 insertions, 0 deletions
diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc
index 5b35390..05843b8 100644
--- a/gcc/tree-inline.cc
+++ b/gcc/tree-inline.cc
@@ -1892,6 +1892,15 @@ remap_gimple_stmt (gimple *stmt, copy_body_data *id)
gimple_call_set_tail (call_stmt, false);
if (gimple_call_from_thunk_p (call_stmt))
gimple_call_set_from_thunk (call_stmt, false);
+ /* Silently clear musttail flag when inlining a function
+ with must tail call from a non-musttail call. The inlining
+ removes one frame so acts like musttail's intent, and we
+ can be inlining a function with musttail calls in the middle
+ of caller where musttail will always error. */
+ if (gimple_call_must_tail_p (call_stmt)
+ && id->call_stmt
+ && !gimple_call_must_tail_p (id->call_stmt))
+ gimple_call_set_must_tail (call_stmt, false);
if (gimple_call_internal_p (call_stmt))
switch (gimple_call_internal_fn (call_stmt))
{