1 /* { dg-do run } */
2 
3 extern void exit (int) __attribute__ ((noreturn));
4 extern void abort (void) __attribute__ ((noreturn));
5 
6 struct t
7 {
8   char dummy;
9 };
10 
11 struct m
12 {
13   const struct t *t;
14   void (*m)(void);
15 };
16 
17 struct s
18 {
19   const struct m *m;
20   void *o;
21 };
22 
23 struct e
24 {
25   const struct t *t;
26   void *o;
27 };
28 
29 struct ret
30 {
31   struct s s;
32   _Bool b;
33 };
34 
35 const struct t t1 = { 1 };
36 const struct t t2 = { 2 };
37 const struct t t3 = { 3 };
38 const struct t t4 = { 4 };
39 const struct t t5 = { 5 };
40 
41 void
pass(void)42 pass (void)
43 {
44   exit (0);
45 }
46 
47 void
fail(void)48 fail (void)
49 {
50   abort ();
51 }
52 
53 const struct m m1 = { &t4, fail };
54 const struct m m2 = { &t5, pass };
55 
56 static struct e f2 (struct s s2, void *p);
57 static struct e f3 (struct s, void *) __attribute__ ((noinline));
58 static void f4 (struct s, void *) __attribute__ ((noinline));
59 
60 struct ret c (struct s, const struct t *) __attribute__ ((noinline));
61 
62 struct ret
c(struct s s1,const struct t * t)63 c (struct s s1, const struct t *t)
64 {
65   struct ret r;
66 
67   if (s1.m->t == t)
68     {
69       r.s.m = &m2;
70       r.s.o = s1.o;
71       r.b = 1;
72     }
73   else
74     {
75       r.s.m = 0;
76       r.s.o = 0;
77       r.b = 0;
78     }
79   return r;
80 }
81 
82 void *m (void) __attribute__ ((noinline));
83 
84 void *
m(void)85 m (void)
86 {
87   return 0;
88 }
89 
90 struct e
f1(struct s s1,void * p)91 f1 (struct s s1, void *p)
92 {
93   struct ret r;
94   void *a;
95   struct s a2;
96 
97   r = c (s1, &t5);
98   if (r.b)
99     return f2 (r.s, p);
100   a = m ();
101   a2.m = &m1;
102   a2.o = a;
103   return f2 (a2, p);
104 }
105 
106 static struct e
f2(struct s s2,void * p)107 f2 (struct s s2, void *p)
108 {
109   struct e e1;
110 
111   e1 = f3 (s2, p);
112   if (e1.t == &t2 && e1.o == 0)
113     {
114       e1.t = 0;
115       e1.o = 0;
116     }
117   return e1;
118 }
119 
120 static struct e
f3(struct s s1,void * p)121 f3 (struct s s1, void *p)
122 {
123   struct e r;
124 
125   f4 (s1, p);
126   r.t = &t3;
127   r.o = 0;
128   return r;
129 }
130 
131 struct s g1;
132 void *g2;
133 
134 static void
f4(struct s s1,void * p)135 f4 (struct s s1, void *p)
136 {
137   g1 = s1;
138   g2 = p;
139   s1.m->m ();
140 }
141 
142 int
main()143 main ()
144 {
145   struct s s1;
146 
147   s1.m = &m2;
148   s1.o = 0;
149   f1 (s1, 0);
150   abort ();
151 }
152