]>
Commit | Line | Data |
---|---|---|
8e7a09c3 JL |
1 | /* On targets where the call instruction is an implicit probe of *sp, we |
2 | elide stack probes as long as the size of the local stack is less than | |
3 | PROBE_INTERVAL. | |
4 | ||
5 | But if the caller were to transform a tail call into a direct jump | |
6 | we do not have that implicit probe. This normally isn't a problem as | |
7 | the caller must not have a local frame for that optimization to apply. | |
8 | ||
9 | However, a sufficiently smart compiler could realize that the caller's | |
10 | local stack need not be torn down and thus could transform a call into | |
11 | a jump if the target is a noreturn function, even if the caller has | |
12 | a local frame. | |
13 | ||
14 | To guard against that, targets that depend on *sp being probed by the | |
15 | call itself must emit a probe if the target function is a noreturn | |
16 | function, even if they just allocate a small amount of stack space. | |
17 | ||
18 | Rather than try to parse RTL or assembly code, we instead require the | |
19 | prologue code to emit information into the dump file that we can | |
20 | scan for. We scan for both the positive and negative cases. */ | |
21 | ||
22 | /* { dg-do compile } */ | |
23 | /* { dg-options "-O2 -fstack-clash-protection -fdump-rtl-pro_and_epilogue -fno-optimize-sibling-calls" } */ | |
24 | /* { dg-require-effective-target supports_stack_clash_protection } */ | |
25 | ||
26 | extern void arf (char *); | |
27 | ||
28 | __attribute__ ((noreturn)) void foo1 () | |
29 | { | |
30 | char x[10]; | |
31 | while (1) | |
32 | arf (x); | |
33 | } | |
34 | ||
35 | void foo2 () | |
36 | { | |
37 | char x[10]; | |
38 | arf (x); | |
39 | } | |
40 | /* { dg-final { scan-rtl-dump-times "Stack clash noreturn" 1 "pro_and_epilogue" } } */ | |
41 | /* { dg-final { scan-rtl-dump-times "Stack clash not noreturn" 1 "pro_and_epilogue" } } */ | |
42 |