1 /* PR c/71924 - missing -Wreturn-local-addr returning alloca result
2 { dg-do compile }
3 { dg-options "-O2 -Wall" }
4 { dg-require-effective-target alloca } */
5
6 #define ATTR(...) __attribute__ ((__VA_ARGS__))
7
8 struct A { int a, b, c; };
9 struct B { int a, b, c[]; };
10
11 extern int g1[5], g2[5], g3[5], g4[5], g5[5];
12
13 void sink (void*, ...);
14
15 ATTR (noipa) void*
16 return_2_locals (int i)
17 {
18 int a[1]; /* { dg-message "declared here" } */
19 int b[2]; /* { dg-message "declared here" } */
20 void *p = b;
21 if (i < 0)
22 p = a;
23
24 sink (p);
25
26 return p; /* { dg-warning "function returns address of local" } */
27 }
28
29 ATTR (noipa) void*
30 return_2_locals_after_2_globals (int i, int j)
31 {
32 int a[1]; /* { dg-message "declared here" } */
33 int b[2]; /* { dg-message "declared here" } */
34
35 int *p;
36 if (i < 0)
37 p = g1;
38 else
39 p = g2;
40
41 sink (p);
42
43 if (j < 0)
44 p = a;
45 else
46 p = b;
47
48 sink (p);
49
50 return p; /* { dg-warning "function returns address of local" } */
51 }
52
53 ATTR (noipa) void*
54 return_3_locals (int i)
55 {
56 int a[1]; /* { dg-message "declared here" } */
57 int b[2]; /* { dg-message "declared here" } */
58 int c[3]; /* { dg-message "declared here" } */
59
60 void *p = b + 1;
61 if (i < 0)
62 p = a;
63 else if (0 < i)
64 p = c + 2;
65
66 sink (p);
67
68 return p; /* { dg-warning "function returns address of local" } */
69 }
70
71 ATTR (noipa) void*
72 return_5_locals (int i)
73 {
74 int a[1]; /* { dg-message "declared here" } */
75 int b[2]; /* { dg-message "declared here" } */
76 int c[3]; /* { dg-message "declared here" } */
77 int d[4]; /* { dg-message "declared here" } */
78 int e[5]; /* { dg-message "declared here" } */
79
80 void *p = &c[2];
81 if (i < -1)
82 p = a;
83 else if (i < 0)
84 p = &b[1];
85 else if (1 < i)
86 p = &e[4];
87 else if (0 < i)
88 p = &d[3];
89
90 sink (p);
91
92 return p; /* { dg-warning "function returns address of local" } */
93 }
94
95 ATTR (noipa) void*
96 return_5_locals_switch (int i)
97 {
98 int a[1]; /* { dg-message "declared here" } */
99 int b[2]; /* { dg-message "declared here" } */
100 int c[3]; /* { dg-message "declared here" } */
101 int d[4]; /* { dg-message "declared here" } */
102 int e[5]; /* { dg-message "declared here" } */
103
104 void *p = 0;
105
106 switch (i)
107 {
108 case 0: p = &a[1]; break;
109 case 1: p = &b[2]; break;
110 case 2: p = &c[3]; break;
111 case 3: p = &d[4]; break;
112 default: p = &e[5]; break;
113 }
114
115 sink (p);
116
117 return p; /* { dg-warning "function returns address of local" } */
118 }
119
120 ATTR (noipa) void*
121 return_1_global_4_locals (int i)
122 {
123 int a[1]; /* { dg-message "declared here" } */
124 int b[2]; /* { dg-message "declared here" } */
125 int c[3]; /* { dg-message "declared here" } */
126 int d[4]; /* { dg-message "declared here" } */
127
128 void *p = c;
129 if (i < -1)
130 sink (p = a);
131 else if (i < 0)
132 sink (p = b);
133 else if (1 < i)
134 sink (p = g1);
135 else if (0 < i)
136 sink (p = d);
137
138 sink (p, a, b, c, d);
139
140 return p; /* { dg-warning "function may return address of local" } */
141 }
142
143 ATTR (noipa) void*
144 return_1_global_4_locals_switch (int i)
145 {
146 int a[1]; /* { dg-message "declared here" } */
147 int b[2]; /* { dg-message "declared here" } */
148 int c[3]; /* { dg-message "declared here" } */
149 int d[4]; /* { dg-message "declared here" } */
150
151 void *p = 0;
152
153 switch (i)
154 {
155 case 0: p = &a[0]; break;
156 case 1: p = &b[1]; break;
157 case 2: p = &c[2]; break;
158 case 3: p = &d[3]; break;
159 }
160
161 sink (p);
162
163 return p; /* { dg-warning "function may return address of local" } */
164 }
165
166 ATTR (noipa) void*
167 return_2_globals_3_locals (int i)
168 {
169 int a[1]; /* { dg-message "declared here" } */
170 int b[2]; /* { dg-message "declared here" } */
171 int c[3]; /* { dg-message "declared here" } */
172
173 void *p = c;
174 if (i < -1)
175 p = a;
176 else if (i < 0)
177 p = b;
178 else if (1 < i)
179 p = g1;
180 else if (0 < i)
181 p = g2;
182
183 sink (p);
184
185 return p; /* { dg-warning "function may return address of local" } */
186 }
187
188 ATTR (noipa) void*
189 return_3_globals_2_locals (int i)
190 {
191 int a[1]; /* { dg-message "declared here" } */
192 int b[2]; /* { dg-message "declared here" } */
193
194 void *p = g3;
195 if (i < -1)
196 p = a;
197 else if (i < 0)
198 p = b;
199 else if (1 < i)
200 p = g1;
201 else if (0 < i)
202 p = g2;
203
204 sink (p);
205
206 return p; /* { dg-warning "function may return address of local" } */
207 }
208
209 ATTR (noipa) void*
210 return_4_globals_1_local (int i)
211 {
212 int a[1]; /* { dg-message "declared here" } */
213
214 void *p = g3;
215 if (i < -1)
216 p = a;
217 else if (i < 0)
218 p = g1;
219 else if (1 < i)
220 p = g2;
221 else if (0 < i)
222 p = g4;
223
224 sink (p);
225
226 return p; /* { dg-warning "function may return address of local" } */
227 }
228
229 ATTR (noipa) void*
230 return_all_globals (int i)
231 {
232 void *p = g4;
233 if (i < -1)
234 p = g1;
235 else if (i < 0)
236 p = g2;
237 else if (1 < i)
238 p = g3;
239 else if (0 < i)
240 p = g5;
241 return p;
242 }
243
244
245 ATTR (noipa) void*
246 return_2_alloca_local_cstoff (int n, int i)
247 {
248 int *a = __builtin_alloca (n); /* { dg-message "declared here" } */
249 int *b = __builtin_alloca (n); /* { dg-message "declared here" } */
250 int *p = i < 0 ? a : b;
251
252 p += 1;
253 sink (p);
254
255 return p; /* { dg-warning "function returns address of local" } */
256 }
257
258 ATTR (noipa) void*
259 return_alloca_local_cstoff (int n, int i)
260 {
261 int *a = __builtin_alloca (n); /* { dg-message "declared here" } */
262 int b[2]; /* { dg-message "declared here" } */
263
264 int *p = b;
265 if (i < 0)
266 p = a;
267
268 p += 1;
269 sink (p);
270
271 return p; /* { dg-warning "function returns address of local" } */
272 }
273
274 ATTR (noipa) void*
275 return_local_alloca_cstoff (int n, int i)
276 {
277 int a[2]; /* { dg-message "declared here" } */
278 int *b = __builtin_alloca (n); /* { dg-message "declared here" } */
279 int *p = b;
280 if (i < 0)
281 p = a;
282
283 p += 1;
284 sink (p);
285
286 return p; /* { dg-warning "function returns address of local" } */
287 }
288
289 ATTR (noipa) void*
290 return_2_locals_cstoff (int i)
291 {
292 int a[1]; /* { dg-message "declared here" } */
293 int b[2]; /* { dg-message "declared here" } */
294
295 int *p = b;
296 if (i < 0)
297 p = a;
298
299 p += 1;
300 sink (p);
301
302 return p; /* { dg-warning "function returns address of local" } */
303 }
304
305 ATTR (noipa) void*
306 return_2_globals_3_locals_cstoff (int i)
307 {
308 int a[1]; /* { dg-message "declared here" } */
309 int b[2]; /* { dg-message "declared here" } */
310 int c[3]; /* { dg-message "declared here" } */
311
312 int *p = c;
313 if (i < -1)
314 p = a;
315 else if (i < 0)
316 p = b;
317 else if (1 < i)
318 p = g1;
319 else if (0 < i)
320 p = g2;
321
322 p += 1;
323 sink (p);
324
325 return p; /* { dg-warning "function may return address of local" } */
326 }
327
328 ATTR (noipa) void*
329 return_3_globals_alloca_local_varoff (int n, int i, int j)
330 {
331 int *a = __builtin_alloca (n); /* { dg-message "declared here" } */
332 int b[2]; /* { dg-message "declared here" } */
333
334 int *p = g3;
335 if (i < -1)
336 p = a;
337 else if (i < 0)
338 p = b;
339 else if (1 < i)
340 p = g1;
341 else if (0 < i)
342 p = g2;
343
344 p += j;
345 sink (p);
346
347 return p; /* { dg-warning "function may return address of local" } */
348 }
349
350 ATTR (noipa) void*
351 return_3_globals_2_locals_varoff (int i, int j)
352 {
353 int a[1]; /* { dg-message "declared here" } */
354 int b[2]; /* { dg-message "declared here" } */
355
356 int *p = g3;
357 if (i < -1)
358 p = a;
359 else if (i < 0)
360 p = b;
361 else if (1 < i)
362 p = g1;
363 else if (0 < i)
364 p = g2;
365
366 p += j;
367 sink (p);
368
369 return p; /* { dg-warning "function may return address of local" } */
370 }
371