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 }