Hi! In the PR119483 r15-9003 change we've allowed musttail calls to noreturn functions, after all the decision not to normally tail call noreturn functions is not because it is not possible to tail call those, but because it screws up backtraces. As the following testcase shows, we've done that only for functions not declared [[noreturn]]/_Noreturn but later on discovered through IPA as noreturn. Functions explicitly declared [[noreturn]] have (for historical reasons) volatile FUNCTION_TYPE and the FUNCTION_DECLs are volatile as well, so in order to support those we shouldn't complain on ECF_NORETURN (we've stopped doing so for musttail in PR119483) but also shouldn't complain about TYPE_VOLATILE on their FUNCTION_TYPE (something that IPA doesn't change, I think it only sets TREE_THIS_VOLATILE on the FUNCTION_DECL). volatile on function type really means noreturn as well, it has no other meaning.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/15.2? 2025-07-29 Jakub Jelinek <ja...@redhat.com> PR middle-end/121159 * calls.cc (can_implement_as_sibling_call_p): Don't reject declared noreturn functions in musttail calls. * c-c++-common/pr121159.c: New test. * gcc.dg/plugin/must-tail-call-2.c (test_5): Don't expect an error. --- gcc/calls.cc.jj 2025-06-04 17:21:01.000000000 +0200 +++ gcc/calls.cc 2025-07-28 11:58:35.205769000 +0200 @@ -2589,7 +2589,8 @@ can_implement_as_sibling_call_p (tree ex return false; } - if (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr)))) + if (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr))) + && !CALL_EXPR_MUST_TAIL_CALL (exp)) { maybe_complain_about_tail_call (exp, _("volatile function type")); return false; --- gcc/testsuite/c-c++-common/pr121159.c.jj 2025-07-28 12:09:37.031226990 +0200 +++ gcc/testsuite/c-c++-common/pr121159.c 2025-07-28 12:09:24.069394221 +0200 @@ -0,0 +1,17 @@ +/* PR middle-end/121159 */ +/* { dg-do compile { target musttail } } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-times "foo \\\(\[^\n\r]*\\\); \\\[tail call\\\] \\\[must tail call\\\]" 1 "optimized" } } */ + +[[noreturn, gnu::noipa]] void +foo (void) +{ + for (;;) + ; +} + +void +bar (void) +{ + [[gnu::musttail]] return foo (); +} --- gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c.jj 2023-03-08 21:44:15.986550516 +0100 +++ gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c 2025-07-29 08:48:30.736998832 +0200 @@ -55,5 +55,5 @@ volatile fn_ptr_t fn_ptr; void test_5 (void) { - fn_ptr (); /* { dg-error "cannot tail-call: " } */ + fn_ptr (); } Jakub