1 /* The goal here is to ensure that we never consider a call to a noreturn
2 function as a potential tail call.
4 Right now GCC discovers potential tail calls by looking at the
5 predecessors of the exit block. A call to a non-return function
6 has no successors and thus can never match that first filter.
8 But that could change one day and we want to catch it. The problem
9 is the compiler could potentially optimize a tail call to a nonreturn
10 function, even if the caller has a frame. That breaks the assumption
11 that calls probe *sp when saving the return address that some targets
12 depend on to elide stack probes. */
14 /* { dg-do compile } */
15 /* { dg-options "-O2 -fstack-clash-protection -fdump-tree-tailc -fdump-tree-optimized" } */
16 /* { dg-require-effective-target supports_stack_clash_protection } */
18 extern void foo (void) __attribute__ ((__noreturn__
));
33 void (*indirect
)(void)__attribute__ ((noreturn
));
43 test_indirect_2 (void)
45 return (*indirect
)();;
49 typedef void (*pvfn
)() __attribute__ ((noreturn
));
51 void (*indirect_casted
)(void);
54 test_indirect_casted_1 ()
56 (*(pvfn
)indirect_casted
)();
60 test_indirect_casted_2 (void)
62 return (*(pvfn
)indirect_casted
)();
64 /* { dg-final { scan-tree-dump-not "tail call" "tailc" } } */
65 /* { dg-final { scan-tree-dump-not "tail call" "optimized" } } */