(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
stack-check-2.c
       1  /* The goal here is to ensure that we never consider a call to a noreturn
       2     function as a potential tail call.
       3  
       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.
       7  
       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.  */
      13  
      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 } */
      17  
      18  extern void foo (void) __attribute__ ((__noreturn__));
      19  
      20  
      21  void
      22  test_direct_1 (void)
      23  {
      24    foo ();
      25  }
      26  
      27  void
      28  test_direct_2 (void)
      29  {
      30    return foo ();
      31  }
      32  
      33  void (*indirect)(void)__attribute__ ((noreturn));
      34  
      35  
      36  void
      37  test_indirect_1 ()
      38  {
      39    (*indirect)();
      40  }
      41  
      42  void
      43  test_indirect_2 (void)
      44  {
      45    return (*indirect)();;
      46  }
      47  
      48  
      49  typedef void (*pvfn)() __attribute__ ((noreturn));
      50  
      51  void (*indirect_casted)(void);
      52  
      53  void
      54  test_indirect_casted_1 ()
      55  {
      56    (*(pvfn)indirect_casted)();
      57  }
      58  
      59  void
      60  test_indirect_casted_2 (void)
      61  {
      62    return (*(pvfn)indirect_casted)();
      63  }
      64  /* { dg-final { scan-tree-dump-not "tail call" "tailc" } } */
      65  /* { dg-final { scan-tree-dump-not "tail call" "optimized" } } */
      66