(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
stack-check-5.c
       1  /* { dg-do compile } */
       2  /* { dg-options "-O2 -fstack-clash-protection -fdump-rtl-pro_and_epilogue -fno-optimize-sibling-calls --param stack-clash-protection-probe-interval=12 --param stack-clash-protection-guard-size=12" } */
       3  /* { dg-require-effective-target supports_stack_clash_protection } */
       4  /* { dg-skip-if "" { *-*-* } { "-fstack-protector*" } { "" } } */
       5  
       6  
       7  /* Otherwise the S/390 back-end might save the stack pointer in f2 ()
       8     into an FPR.  */
       9  /* { dg-additional-options "-msoft-float" { target { s390x-*-* } } } */
      10  
      11  extern void foo (char *);
      12  extern void bar (void);
      13  
      14  /* This function allocates no local stack and is a leaf.  It should have no
      15     probes on any target and should not require a frame pointer.  */
      16  int
      17  f0 (int x, int y)
      18  {
      19    asm volatile ("" : : : "memory");  
      20    return x + y;
      21  }
      22  
      23  /* This function allocates no local stack, but is not a leaf.  Ideally it
      24     should not need probing and no frame pointer.  */
      25  int
      26  f1 (int x, int y)
      27  {
      28    asm volatile ("" : : : "memory");  
      29    bar ();
      30  }
      31  
      32  /* This is a leaf with a small frame.  On targets with implicit probes in
      33     the caller, this should not need probing.  On targets with no implicit
      34     probes in the caller, it may require probes.  Ideally it should need no
      35     frame pointer.  */
      36  void
      37  f2 (void)
      38  {
      39    char buf[512];
      40    asm volatile ("" : : "g" (&buf) : "memory");
      41  }
      42  
      43  /* This is a non-leaf with a small frame.  On targets with implicit probes in
      44     the caller, this should not need probing.  On targets with no implicit
      45     probes in the caller, it may require probes.  It should need no frame
      46     pointer.  */
      47  void
      48  f3 (void)
      49  {
      50    char buf[512];
      51    foo (buf);
      52  }
      53  
      54  /* If we have caller implicit probes, then we should not need probes.
      55     Else callees may need probes, particularly if non-leaf functions require a
      56     frame/frame pointer.  */
      57  /* { dg-final { scan-rtl-dump-times "Stack clash no probe" 4 "pro_and_epilogue" { target caller_implicit_probes } } } */
      58  /* { dg-final { scan-rtl-dump-times "Stack clash no probe" 2 "pro_and_epilogue" { target { ! caller_implicit_probes } } } } */
      59  /* { dg-final { scan-rtl-dump-times "Stack clash inline probes " 2 "pro_and_epilogue" { target { ! caller_implicit_probes } } } } */
      60  
      61  /* None of these functions are marked with the noreturn attribute.  */
      62  /* { dg-final { scan-rtl-dump-times "Stack clash not noreturn" 4 "pro_and_epilogue" } } */
      63  
      64  /* Two functions are leafs, two are not.  Verify the target identified them
      65     appropriately.  */
      66  /* { dg-final { scan-rtl-dump-times "Stack clash no frame pointer needed" 4 "pro_and_epilogue" { target { ! frame_pointer_for_non_leaf } } } } */
      67  /* { dg-final { scan-rtl-dump-times "Stack clash no frame pointer needed" 2 "pro_and_epilogue" { target { frame_pointer_for_non_leaf } } } } */
      68  /* { dg-final { scan-rtl-dump-times "Stack clash frame pointer needed" 2 "pro_and_epilogue" { target { frame_pointer_for_non_leaf } } } } */
      69  /* AArch64 won't require a probe here due to the allocation amount being less than 1KB.  */
      70  /* { dg-final { scan-rtl-dump-times "Stack clash no probe small stack adjustment in prologue" 3 "pro_and_epilogue" { target { aarch64*-*-* } } } } */
      71  /* { dg-final { scan-rtl-dump-times "Stack clash no probe no stack adjustment in prologue" 1 "pro_and_epilogue" { target { aarch64*-*-* } } } } */
      72  
      73  /* We have selected the size of the array in f2/f3 to be large enough
      74     to not live in the red zone on targets that support it.
      75  
      76     That allows simplification of this test considerably.
      77     f1() should not require any allocations, thus no residuals.
      78     All the rest of the functions require some kind of allocation,
      79     either for the saved fp/rp or the array.  */
      80  /* { dg-final { scan-rtl-dump-times "Stack clash no residual allocation in prologue" 1 "pro_and_epilogue" } } */
      81  /* { dg-final { scan-rtl-dump-times "Stack clash residual allocation in prologue" 3 "pro_and_epilogue" } } */