1 /* PR tree-optimization/86552 - missing warning for reading past the end
2 of non-string arrays
3 { dg-do compile }
4 { dg-options "-O2 -Wall -Wno-array-bounds -ftrack-macro-expansion=0" } */
5
6 extern char* stpcpy (char*, const char*);
7
8 const char a[5] = "12345"; /* { dg-message "declared here" } */
9
10 int v0 = 0;
11 int v1 = 1;
12 int v2 = 1;
13 int v3 = 1;
14
15 void sink (char*, ...);
16
17 #define T(str) sink (stpcpy (d, str))
18
test_one_dim_array(char * d)19 void test_one_dim_array (char *d)
20 {
21 T (a); /* { dg-warning "argument missing terminating nul" } */
22 T (&a[0]); /* { dg-warning "nul" } */
23 T (&a[0] + 1); /* { dg-warning "nul" } */
24 T (&a[1]); /* { dg-warning "nul" } */
25
26 int i0 = 0;
27 int i1 = i0 + 1;
28
29 T (&a[i0]); /* { dg-warning "nul" } */
30 T (&a[i0] + 1); /* { dg-warning "nul" } */
31 T (&a[i1]); /* { dg-warning "nul" } */
32
33 T (&a[v0]); /* { dg-warning "nul" } */
34 T (&a[v0] + 1); /* { dg-warning "nul" } */
35 T (&a[v0] + v1); /* { dg-warning "nul" } */
36 }
37
38 const char b[][5] = { /* { dg-message "declared here" } */
39 "12", "123", "1234", "54321"
40 };
41
test_two_dim_array(char * d)42 void test_two_dim_array (char *d)
43 {
44 int i0 = 0;
45 int i1 = i0 + 1;
46 int i2 = i1 + 1;
47 int i3 = i2 + 1;
48
49 T (b[0]);
50 T (b[1]);
51 T (b[2]);
52 T (b[3]); /* { dg-warning "nul" } */
53 T (b[i0]);
54 T (b[i1]);
55 T (b[i2]);
56 T (b[i3]); /* { dg-warning "nul" } */
57 T (b[v0]);
58 T (b[v3]);
59
60 T (&b[2][1]);
61 T (&b[2][1] + 1);
62 T (&b[2][v0]);
63 T (&b[2][1] + v0);
64
65 T (&b[i2][i1]);
66 T (&b[i2][i1] + i1);
67 T (&b[i2][v0]);
68 T (&b[i2][i1] + v0);
69
70 T (&b[3][1]); /* { dg-warning "nul" } */
71 T (&b[3][1] + 1); /* { dg-warning "nul" } */
72 T (&b[3][v0]); /* { dg-warning "nul" } */
73 T (&b[3][1] + v0); /* { dg-warning "nul" } */
74 T (&b[3][v0] + v1); /* { dg-warning "nul" } */
75
76 T (&b[i3][i1]); /* { dg-warning "nul" } */
77 T (&b[i3][i1] + i1); /* { dg-warning "nul" } */
78 T (&b[i3][v0]); /* { dg-warning "nul" } */
79 T (&b[i3][i1] + v0); /* { dg-warning "nul" } */
80 T (&b[i3][v0] + v1); /* { dg-warning "nul" } */
81
82 T (v0 ? "" : b[0]);
83 T (v0 ? "" : b[1]);
84 T (v0 ? "" : b[2]);
85 T (v0 ? "" : b[3]); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
86 T (v0 ? b[0] : "");
87 T (v0 ? b[1] : "");
88 T (v0 ? b[2] : "");
89 T (v0 ? b[3] : ""); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
90
91 T (v0 ? "1234" : b[3]); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
92 T (v0 ? b[3] : "1234"); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
93
94 T (v0 ? a : b[3]); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
95 T (v0 ? b[0] : b[2]);
96 T (v0 ? b[2] : b[3]); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
97 T (v0 ? b[3] : b[2]); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
98
99 T (v0 ? b[0] : &b[3][0] + 1); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
100 T (v0 ? b[1] : &b[3][1] + v0); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
101
102 /* It's possible to detect the missing nul in the following two
103 expressions but GCC doesn't do it yet. */
104 T (v0 ? &b[3][1] + v0 : b[2]); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
105 T (v0 ? &b[3][v0] : &b[3][v1]); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
106 }
107
108 struct A { char a[5], b[5]; };
109
110 const struct A s = { "1234", "12345" };
111
test_struct_member(char * d)112 void test_struct_member (char *d)
113 {
114 int i0 = 0;
115 int i1 = i0 + 1;
116
117 T (s.a);
118 T (&s.a[0]);
119 T (&s.a[0] + 1);
120 T (&s.a[0] + i0);
121 T (&s.a[1]);
122 T (&s.a[1] + 1);
123 T (&s.a[1] + i0);
124
125 T (&s.a[i0]);
126 T (&s.a[i0] + 1);
127 T (&s.a[i0] + v0);
128 T (&s.a[i1]);
129 T (&s.a[i1] + 1);
130 T (&s.a[i1] + v0);
131
132 T (s.a);
133 T (&s.a[0]);
134 T (&s.a[0] + 1);
135 T (&s.a[0] + v0);
136 T (&s.a[1]);
137 T (&s.a[1] + 1);
138 T (&s.a[1] + v0);
139
140 T (&s.a[i0]);
141 T (&s.a[i0] + 1);
142 T (&s.a[i0] + v0);
143 T (&s.a[i1]);
144 T (&s.a[i1] + 1);
145 T (&s.a[i1] + v0);
146
147 T (&s.a[v0]);
148 T (&s.a[v0] + 1);
149 T (&s.a[v0] + v0);
150 T (&s.a[v1]);
151 T (&s.a[v1] + 1);
152 T (&s.a[v1] + v0);
153
154 T (s.b); /* { dg-warning "nul" } */
155 T (&s.b[0]); /* { dg-warning "nul" } */
156 T (&s.b[0] + 1); /* { dg-warning "nul" } */
157 T (&s.b[0] + i0); /* { dg-warning "nul" } */
158 T (&s.b[1]); /* { dg-warning "nul" } */
159 T (&s.b[1] + 1); /* { dg-warning "nul" } */
160 T (&s.b[1] + i0); /* { dg-warning "nul" } */
161
162 T (s.b); /* { dg-warning "nul" } */
163 T (&s.b[0]); /* { dg-warning "nul" } */
164 T (&s.b[0] + 1); /* { dg-warning "nul" } */
165 T (&s.b[0] + v0); /* { dg-warning "nul" } */
166 T (&s.b[1]); /* { dg-warning "nul" } */
167 T (&s.b[1] + 1); /* { dg-warning "nul" } */
168 T (&s.b[1] + v0); /* { dg-warning "nul" } */
169
170 T (s.b); /* { dg-warning "nul" } */
171 T (&s.b[v0]); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
172 T (&s.b[v0] + 1); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
173 T (&s.b[v0] + v0); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
174 T (&s.b[v1]); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
175 T (&s.b[v1] + 1); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
176 T (&s.b[v1] + v0); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
177 }
178
179 struct B { struct A a[2]; };
180
181 const struct B ba[] = {
182 { { { "123", "12345" }, { "12345", "123" } } },
183 { { { "12345", "123" }, { "123", "12345" } } },
184 { { { "1", "12" }, { "123", "1234" } } },
185 { { { "123", "1234" }, { "12345", "12" } } }
186 };
187
test_array_of_structs(char * d)188 void test_array_of_structs (char *d)
189 {
190 T (ba[0].a[0].a);
191 T (&ba[0].a[0].a[0]);
192 T (&ba[0].a[0].a[0] + 1);
193 T (&ba[0].a[0].a[0] + v0);
194 T (&ba[0].a[0].a[1]);
195 T (&ba[0].a[0].a[1] + 1);
196 T (&ba[0].a[0].a[1] + v0);
197
198 T (ba[0].a[0].b); /* { dg-warning "nul" } */
199 T (&ba[0].a[0].b[0]); /* { dg-warning "nul" } */
200 T (&ba[0].a[0].b[0] + 1); /* { dg-warning "nul" } */
201 T (&ba[0].a[0].b[0] + v0); /* { dg-warning "nul" } */
202 T (&ba[0].a[0].b[1]); /* { dg-warning "nul" } */
203 T (&ba[0].a[0].b[1] + 1); /* { dg-warning "nul" } */
204 T (&ba[0].a[0].b[1] + v0); /* { dg-warning "nul" } */
205
206 T (ba[0].a[1].a); /* { dg-warning "nul" } */
207 T (&ba[0].a[1].a[0]); /* { dg-warning "nul" } */
208 T (&ba[0].a[1].a[0] + 1); /* { dg-warning "nul" } */
209 T (&ba[0].a[1].a[0] + v0); /* { dg-warning "nul" } */
210 T (&ba[0].a[1].a[1]); /* { dg-warning "nul" } */
211 T (&ba[0].a[1].a[1] + 1); /* { dg-warning "nul" } */
212 T (&ba[0].a[1].a[1] + v0); /* { dg-warning "nul" } */
213
214 T (ba[0].a[1].b);
215 T (&ba[0].a[1].b[0]);
216 T (&ba[0].a[1].b[0] + 1);
217 T (&ba[0].a[1].b[0] + v0);
218 T (&ba[0].a[1].b[1]);
219 T (&ba[0].a[1].b[1] + 1);
220 T (&ba[0].a[1].b[1] + v0);
221
222
223 T (ba[1].a[0].a); /* { dg-warning "nul" } */
224 T (&ba[1].a[0].a[0]); /* { dg-warning "nul" } */
225 T (&ba[1].a[0].a[0] + 1); /* { dg-warning "nul" } */
226 T (&ba[1].a[0].a[0] + v0); /* { dg-warning "nul" } */
227 T (&ba[1].a[0].a[1]); /* { dg-warning "nul" } */
228 T (&ba[1].a[0].a[1] + 1); /* { dg-warning "nul" } */
229 T (&ba[1].a[0].a[1] + v0); /* { dg-warning "nul" } */
230
231 T (ba[1].a[0].b);
232 T (&ba[1].a[0].b[0]);
233 T (&ba[1].a[0].b[0] + 1);
234 T (&ba[1].a[0].b[0] + v0);
235 T (&ba[1].a[0].b[1]);
236 T (&ba[1].a[0].b[1] + 1);
237 T (&ba[1].a[0].b[1] + v0);
238
239 T (ba[1].a[1].a);
240 T (&ba[1].a[1].a[0]);
241 T (&ba[1].a[1].a[0] + 1);
242 T (&ba[1].a[1].a[0] + v0);
243 T (&ba[1].a[1].a[1]);
244 T (&ba[1].a[1].a[1] + 1);
245 T (&ba[1].a[1].a[1] + v0);
246
247 T (ba[1].a[1].b); /* { dg-warning "nul" } */
248 T (&ba[1].a[1].b[0]); /* { dg-warning "nul" } */
249 T (&ba[1].a[1].b[0] + 1); /* { dg-warning "nul" } */
250 T (&ba[1].a[1].b[0] + v0); /* { dg-warning "nul" } */
251 T (&ba[1].a[1].b[1]); /* { dg-warning "nul" } */
252 T (&ba[1].a[1].b[1] + 1); /* { dg-warning "nul" } */
253 T (&ba[1].a[1].b[1] + v0); /* { dg-warning "nul" } */
254
255
256 T (ba[2].a[0].a);
257 T (&ba[2].a[0].a[0]);
258 T (&ba[2].a[0].a[0] + 1);
259 T (&ba[2].a[0].a[0] + v0);
260 T (&ba[2].a[0].a[1]);
261 T (&ba[2].a[0].a[1] + 1);
262 T (&ba[2].a[0].a[1] + v0);
263
264 T (ba[2].a[0].b);
265 T (&ba[2].a[0].b[0]);
266 T (&ba[2].a[0].b[0] + 1);
267 T (&ba[2].a[0].b[0] + v0);
268 T (&ba[2].a[0].b[1]);
269 T (&ba[2].a[0].b[1] + 1);
270 T (&ba[2].a[0].b[1] + v0);
271
272 T (ba[2].a[1].a);
273 T (&ba[2].a[1].a[0]);
274 T (&ba[2].a[1].a[0] + 1);
275 T (&ba[2].a[1].a[0] + v0);
276 T (&ba[2].a[1].a[1]);
277 T (&ba[2].a[1].a[1] + 1);
278 T (&ba[2].a[1].a[1] + v0);
279
280
281 T (ba[3].a[0].a);
282 T (&ba[3].a[0].a[0]);
283 T (&ba[3].a[0].a[0] + 1);
284 T (&ba[3].a[0].a[0] + v0);
285 T (&ba[3].a[0].a[1]);
286 T (&ba[3].a[0].a[1] + 1);
287 T (&ba[3].a[0].a[1] + v0);
288
289 T (ba[3].a[0].b);
290 T (&ba[3].a[0].b[0]);
291 T (&ba[3].a[0].b[0] + 1);
292 T (&ba[3].a[0].b[0] + v0);
293 T (&ba[3].a[0].b[1]);
294 T (&ba[3].a[0].b[1] + 1);
295 T (&ba[3].a[0].b[1] + v0);
296
297 T (ba[3].a[1].a); /* { dg-warning "nul" } */
298 T (&ba[3].a[1].a[0]); /* { dg-warning "nul" } */
299 T (&ba[3].a[1].a[0] + 1); /* { dg-warning "nul" } */
300 T (&ba[3].a[1].a[0] + v0); /* { dg-warning "nul" } */
301 T (&ba[3].a[1].a[1]); /* { dg-warning "nul" } */
302 T (&ba[3].a[1].a[1] + 1); /* { dg-warning "nul" } */
303 T (&ba[3].a[1].a[1] + v0); /* { dg-warning "nul" } */
304
305 T (ba[3].a[1].b);
306 T (&ba[3].a[1].b[0]);
307 T (&ba[3].a[1].b[0] + 1);
308 T (&ba[3].a[1].b[0] + v0);
309 T (&ba[3].a[1].b[1]);
310 T (&ba[3].a[1].b[1] + 1);
311 T (&ba[3].a[1].b[1] + v0);
312
313
314 T (v0 ? ba[0].a[0].a : ba[0].a[0].b); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
315 T (v0 ? ba[0].a[0].a : ba[0].a[0].b); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
316
317 T (v0 ? &ba[0].a[0].a[0] : &ba[3].a[1].a[0]); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
318 T (v0 ? &ba[3].a[1].a[1] : ba[0].a[0].a); /* { dg-warning "nul" "bug ???" { xfail *-*-* } } */
319
320 T (v0 ? ba[0].a[0].a : ba[0].a[1].b);
321 T (v0 ? ba[0].a[1].b : ba[0].a[0].a);
322 }
323
324 /* { dg-prune-output " reading \[1-9\]\[0-9\]? bytes from a region " } */
325