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