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