]>
Commit | Line | Data |
---|---|---|
aac9480d MS |
1 | /* PR c/71924 - missing -Wreturn-local-addr returning alloca result |
2 | { dg-do compile } | |
ebd20377 TV |
3 | { dg-options "-O2 -Wall" } |
4 | { dg-require-effective-target alloca } */ | |
aac9480d MS |
5 | |
6 | #define ATTR(...) __attribute__ ((__VA_ARGS__)) | |
7 | ||
8 | typedef __INTPTR_TYPE__ intptr_t; | |
9 | ||
10 | struct A { int a, b, c; }; | |
11 | struct B { int a, b, c[]; }; | |
12 | ||
13 | extern int g1[5], g2[5], g3[5], g4[5], g5[5]; | |
14 | ||
15 | void sink (void*, ...); | |
16 | ||
17 | /* Verify that a pointer difference expression is handled correctly | |
18 | even when converted to a pointer. */ | |
19 | ||
20 | ATTR (noipa) void* | |
21 | return_local_diff_cst (void) | |
22 | { | |
23 | int a[5]; | |
24 | void *p = (void*)(&a[4] - &a[1]); | |
25 | return p; | |
26 | } | |
27 | ||
28 | ATTR (noipa) void* | |
29 | return_local_diff_var (int i, int j) | |
30 | { | |
31 | int a[5]; | |
32 | void *p = (void*)(&a[j] - &a[i]); | |
33 | return p; | |
34 | } | |
35 | ||
36 | ATTR (noipa) void* | |
37 | return_2_locals (int i) | |
38 | { | |
39 | int a[1]; /* { dg-message "declared here" } */ | |
40 | int b[2]; /* { dg-message "declared here" } */ | |
41 | void *p = i < 0 ? a : b; | |
42 | return p; /* { dg-warning "function returns address of local" } */ | |
43 | } | |
44 | ||
45 | /* Verify that returning the address of a local converted to intptr_t | |
46 | is not diagnosed (see bug 90737 for a case the front-end gets wrong). */ | |
47 | ||
48 | ATTR (noipa) intptr_t | |
49 | return_int_2_locals (int i) | |
50 | { | |
51 | int a[1]; | |
52 | int b[2]; | |
53 | void *p = i < 0 ? a : b; | |
54 | return (intptr_t)p; | |
55 | } | |
56 | ||
57 | /* Verify that a conditional expression with a pointer first operand | |
58 | is handled correctly. */ | |
59 | ||
60 | ATTR (noipa) void* | |
61 | return_2_locals_ptrcond (void *q) | |
62 | { | |
63 | int a[1]; /* { dg-message "declared here" } */ | |
64 | int b[2]; /* { dg-message "declared here" } */ | |
65 | void *p = q ? a : b; | |
66 | return p; /* { dg-warning "function returns address of local" } */ | |
67 | } | |
68 | ||
69 | /* Verify that a preincrement expression with a pointer operand is | |
70 | handled correctly. */ | |
71 | ||
72 | ATTR (noipa) void* | |
73 | return_2_locals_ptrinc (void *q) | |
74 | { | |
75 | int a[1]; /* { dg-message "declared here" } */ | |
76 | int b[2]; /* { dg-message "declared here" } */ | |
77 | int *p = q ? a : b; | |
78 | return ++p; /* { dg-warning "function returns address of local" } */ | |
79 | } | |
80 | ||
81 | ATTR (noipa) void* | |
82 | return_3_locals (int i) | |
83 | { | |
84 | int a[1]; /* { dg-message "declared here" } */ | |
85 | int b[2]; /* { dg-message "declared here" } */ | |
86 | int c[3]; /* { dg-message "declared here" } */ | |
87 | ||
88 | void *p = i < 0 ? a : 0 < i ? c : b; | |
89 | return p; /* { dg-warning "function returns address of local" } */ | |
90 | } | |
91 | ||
92 | /* Verify that a conditional expression with a pointer first operand | |
93 | is handled correctly. */ | |
94 | ||
95 | ATTR (noipa) void* | |
96 | return_3_locals_ptrcond (void *p, void *q) | |
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 | ||
102 | void *r = q ? r ? a : b : c; | |
103 | return r; /* { dg-warning "function returns address of local" } */ | |
104 | } | |
105 | ||
106 | ATTR (noipa) void* | |
107 | return_5_locals (int i) | |
108 | { | |
109 | int a[1]; /* { dg-message "declared here" } */ | |
110 | int b[2]; /* { dg-message "declared here" } */ | |
111 | int c[3]; /* { dg-message "declared here" } */ | |
112 | int d[4]; /* { dg-message "declared here" } */ | |
113 | int e[5]; /* { dg-message "declared here" } */ | |
114 | ||
115 | void *p = i < -1 ? a : i < 0 ? b : 1 < i ? e : 0 < i ? d : c; | |
116 | return p; /* { dg-warning "function returns address of local" } */ | |
117 | } | |
118 | ||
119 | ATTR (noipa) void* | |
120 | return_1_global_4_locals (int i) | |
121 | { | |
122 | int a[1]; /* { dg-message "declared here" } */ | |
123 | int b[2]; /* { dg-message "declared here" } */ | |
124 | int c[3]; /* { dg-message "declared here" } */ | |
125 | int d[4]; /* { dg-message "declared here" } */ | |
126 | ||
127 | void *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? d : c; | |
128 | return p; /* { dg-warning "function may return address of local" } */ | |
129 | } | |
130 | ||
131 | ATTR (noipa) void* | |
132 | return_2_globals_3_locals (int i) | |
133 | { | |
134 | int a[1]; /* { dg-message "declared here" } */ | |
135 | int b[2]; /* { dg-message "declared here" } */ | |
136 | int c[3]; /* { dg-message "declared here" } */ | |
137 | ||
138 | void *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? g2 : c; | |
139 | return p; /* { dg-warning "function may return address of local" } */ | |
140 | } | |
141 | ||
142 | ATTR (noipa) void* | |
143 | return_3_globals_2_locals (int i) | |
144 | { | |
145 | int a[1]; /* { dg-message "declared here" } */ | |
146 | int b[2]; /* { dg-message "declared here" } */ | |
147 | ||
148 | void *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? g2 : g3; | |
149 | return p; /* { dg-warning "function may return address of local" } */ | |
150 | } | |
151 | ||
152 | ATTR (noipa) void* | |
153 | return_4_globals_1_local (int i) | |
154 | { | |
155 | int a[1]; /* { dg-message "declared here" } */ | |
156 | ||
157 | void *p = i < -1 ? a : i < 0 ? g1 : 1 < i ? g2 : 0 < i ? g4 : g3; | |
158 | return p; /* { dg-warning "function may return address of local" } */ | |
159 | } | |
160 | ||
161 | ATTR (noipa) void* | |
162 | return_all_globals (int i) | |
163 | { | |
164 | void *p = i < -1 ? g1 : i < 0 ? g2 : 1 < i ? g3 : 0 < i ? g5 : g4; | |
165 | return p; | |
166 | } | |
167 | ||
168 | ||
169 | ATTR (noipa) void* | |
170 | return_2_alloca_local_cstoff (int n, int i) | |
171 | { | |
172 | int *a = __builtin_alloca (n); /* { dg-message "declared here" } */ | |
173 | int *b = __builtin_alloca (n); /* { dg-message "declared here" } */ | |
174 | int *p = i < 0 ? a : b; | |
175 | p += 1; | |
176 | sink (p); | |
177 | return p; /* { dg-warning "function returns address of local" } */ | |
178 | } | |
179 | ||
180 | ATTR (noipa) void* | |
181 | return_alloca_local_cstoff (int n, int i) | |
182 | { | |
183 | int *a = __builtin_alloca (n); /* { dg-message "declared here" } */ | |
184 | int b[2]; /* { dg-message "declared here" } */ | |
185 | int *p = i < 0 ? a : b; | |
186 | p += 1; | |
187 | sink (p); | |
188 | return p; /* { dg-warning "function returns address of local" } */ | |
189 | } | |
190 | ||
191 | ATTR (noipa) void* | |
192 | return_local_alloca_cstoff (int n, int i) | |
193 | { | |
194 | int a[2]; /* { dg-message "declared here" } */ | |
195 | int *b = __builtin_alloca (n); /* { dg-message "declared here" } */ | |
196 | int *p = i < 0 ? a : b; | |
197 | p += 1; | |
198 | sink (p); | |
199 | return p; /* { dg-warning "function returns address of local" } */ | |
200 | } | |
201 | ||
202 | ATTR (noipa) void* | |
203 | return_2_locals_cstoff (int i) | |
204 | { | |
205 | int a[1]; /* { dg-message "declared here" } */ | |
206 | int b[2]; /* { dg-message "declared here" } */ | |
207 | int *p = i < 0 ? a : b; | |
208 | p += 1; | |
209 | sink (p); | |
210 | return p; /* { dg-warning "function returns address of local" } */ | |
211 | } | |
212 | ||
213 | ATTR (noipa) void* | |
214 | return_2_globals_3_locals_cstoff (int i) | |
215 | { | |
216 | int a[1]; /* { dg-message "declared here" } */ | |
217 | int b[2]; /* { dg-message "declared here" } */ | |
218 | int c[3]; /* { dg-message "declared here" } */ | |
219 | ||
220 | int *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? g2 : c; | |
221 | p += 1; | |
222 | sink (p); | |
223 | return p; /* { dg-warning "function may return address of local" } */ | |
224 | } | |
225 | ||
226 | ATTR (noipa) void* | |
227 | return_3_globals_alloca_local_varoff (int n, int i, int j) | |
228 | { | |
229 | int *a = __builtin_alloca (n); /* { dg-message "declared here" } */ | |
230 | int b[2]; /* { dg-message "declared here" } */ | |
231 | ||
232 | int *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? g2 : g3; | |
233 | p += j; | |
234 | sink (p); | |
235 | return p; /* { dg-warning "function may return address of local" } */ | |
236 | } | |
237 | ||
238 | ATTR (noipa) void* | |
239 | return_3_globals_2_locals_varoff (int i, int j) | |
240 | { | |
241 | int a[1]; /* { dg-message "declared here" } */ | |
242 | int b[2]; /* { dg-message "declared here" } */ | |
243 | ||
244 | int *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? g2 : g3; | |
245 | p += j; | |
246 | sink (p); | |
247 | return p; /* { dg-warning "function may return address of local" } */ | |
248 | } | |
249 |