1
2 extern void exit (int);
3 extern void abort (void);
4 extern void *alloca (__SIZE_TYPE__);
5 char *dummy (void);
6
7 #define NOINLINE __attribute__((noinline))
8
9 void *save_ret1[6];
10 void *test4a (char *);
11 void *test5a (char *);
12 void *test6a (char *);
13
test1(void)14 void NOINLINE *test1 (void)
15 {
16 void * temp;
17 temp = __builtin_return_address (0);
18 return temp;
19 }
20
test2(void)21 void NOINLINE *test2 (void)
22 {
23 void * temp;
24 dummy ();
25 temp = __builtin_return_address (0);
26 return temp;
27 }
28
test3(void)29 void NOINLINE *test3 (void)
30 {
31 void * temp;
32 temp = __builtin_return_address (0);
33 dummy ();
34 return temp;
35 }
36
test4(void)37 void NOINLINE *test4 (void)
38 {
39 char * save = (char*) alloca (4);
40
41 return test4a (save);
42 }
43
test4a(char * p)44 void *NOINLINE test4a (char * p)
45 {
46 void * temp;
47 temp = __builtin_return_address (1);
48 return temp;
49 }
50
test5(void)51 void NOINLINE *test5 (void)
52 {
53 char * save = (char*) alloca (4);
54
55 return test5a (save);
56 }
57
test5a(char * p)58 void NOINLINE *test5a (char * p)
59 {
60 void * temp;
61 dummy ();
62 temp = __builtin_return_address (1);
63 return temp;
64 }
65
test6(void)66 void NOINLINE *test6 (void)
67 {
68 char * save = (char*) alloca (4);
69
70 return test6a (save);
71 }
72
test6a(char * p)73 void NOINLINE *test6a (char * p)
74 {
75 void * temp;
76 temp = __builtin_return_address (1);
77 dummy ();
78 return temp;
79 }
80
81 void *(*func1[6])(void) = { test1, test2, test3, test4, test5, test6 };
82
call_func1(int i)83 char * NOINLINE call_func1 (int i)
84 {
85 save_ret1[i] = func1[i] ();
86 }
87
88 static void *ret_addr;
89 void *save_ret2[6];
90 void test10a (char *);
91 void test11a (char *);
92 void test12a (char *);
93
test7(void)94 void NOINLINE test7 (void)
95 {
96 ret_addr = __builtin_return_address (0);
97 return;
98 }
99
test8(void)100 void NOINLINE test8 (void)
101 {
102 dummy ();
103 ret_addr = __builtin_return_address (0);
104 return;
105 }
106
test9(void)107 void NOINLINE test9 (void)
108 {
109 ret_addr = __builtin_return_address (0);
110 dummy ();
111 return;
112 }
113
test10(void)114 void NOINLINE test10 (void)
115 {
116 char * save = (char*) alloca (4);
117
118 test10a (save);
119 }
120
test10a(char * p)121 void NOINLINE test10a (char * p)
122 {
123 ret_addr = __builtin_return_address (1);
124 return;
125 }
126
test11(void)127 void NOINLINE test11 (void)
128 {
129 char * save = (char*) alloca (4);
130
131 test11a (save);
132 }
133
test11a(char * p)134 void NOINLINE test11a (char * p)
135 {
136 dummy ();
137 ret_addr = __builtin_return_address (1);
138 return;
139 }
140
test12(void)141 void NOINLINE test12 (void)
142 {
143 char * save = (char*) alloca (4);
144
145 test12a (save);
146 }
147
test12a(char * p)148 void NOINLINE test12a (char * p)
149 {
150 ret_addr = __builtin_return_address (1);
151 dummy ();
152 return;
153 }
154
dummy(void)155 char * dummy (void)
156 {
157 char * save = (char*) alloca (4);
158
159 return save;
160 }
161
162 void (*func2[6])(void) = { test7, test8, test9, test10, test11, test12 };
163
call_func2(int i)164 void NOINLINE call_func2 (int i)
165 {
166 func2[i] ();
167 save_ret2[i] = ret_addr;
168 }
169
main(void)170 int main (void)
171 {
172 int i;
173
174 for (i = 0; i < 6; i++) {
175 call_func1(i);
176 }
177
178 if (save_ret1[0] != save_ret1[1]
179 || save_ret1[1] != save_ret1[2])
180 abort ();
181 if (save_ret1[3] != save_ret1[4]
182 || save_ret1[4] != save_ret1[5])
183 abort ();
184 if (save_ret1[3] && save_ret1[0] != save_ret1[3])
185 abort ();
186
187
188 for (i = 0; i < 6; i++) {
189 call_func2(i);
190 }
191
192 if (save_ret2[0] != save_ret2[1]
193 || save_ret2[1] != save_ret2[2])
194 abort ();
195 if (save_ret2[3] != save_ret2[4]
196 || save_ret2[4] != save_ret2[5])
197 abort ();
198 if (save_ret2[3] && save_ret2[0] != save_ret2[3])
199 abort ();
200
201 exit (0);
202 }
203