(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wreturn-local-addr-10.c
       1  /* PR c/71924 - missing -Wreturn-local-addr returning alloca result
       2     Test reduced from libstdc++-v3/testsuite/ext/ext_pointer/1.cc.
       3     It verifies that iteration in find_implicit_erroneous_behavior
       4     in gimple-ssa-isolate-path.c terminates under specific conditions.
       5     { dg-do compile }
       6     { dg-options "-O2 -Wall" } */
       7  
       8  typedef __UINTPTR_TYPE__ uintptr_t;
       9  
      10  struct A { int i; };
      11  struct P { uintptr_t d; };
      12  
      13  static inline struct A* get (const struct P *p)
      14  {
      15    if (p->d == 1)
      16      return 0;
      17  
      18    return (struct A*)((uintptr_t)p + p->d);
      19  }
      20  
      21  static inline void set (struct P *p, struct A* q)
      22  {
      23    /* The basic block below would cause an infinite loop in
      24       find_implicit_erroneous_behavior due to assuming the DUPLICATE
      25       pointer returned from isolate_path would distinct from the one
      26       passed to it.  (Replacing the if statement with the ternary ?:
      27       expression did not have this effect (it gets optimized early
      28       on).
      29      <bb 4> [local count: 1073741823]:
      30      # _14 = PHI <0B(2), &MEM <struct A[2]> [(void *)&a + 4B](3)>
      31      _2 = _14->i;
      32      if (_2 != 2)
      33        goto <bb 5>; [0.00%]
      34      else
      35        goto <bb 6>; [100.00%]
      36    */
      37    if (!q)
      38      p->d = 1;
      39    else
      40      p->d = (uintptr_t)(q) - (uintptr_t)(p);
      41  }
      42  
      43  void f (void)
      44  {
      45    struct A a[2] = { { 1 }, { 2 } };
      46  
      47    struct P p, q;
      48    set (&p, a);
      49    set (&q, get (&p));
      50  
      51    set (&q, get (&q) + 0);
      52    set (&q, get (&q) + 1);
      53  
      54    if (get (&q)[0].i != get (&p)[1].i)
      55      __builtin_abort ();
      56  }