1 /* Verify -Wstringop-overread is issued appropriately for calls to string
2 functions at -O0 and without -Wall.
3 { dg-do compile }
4 { dg-options "-O0 -ftrack-macro-expansion=0" } */
5
6 typedef __SIZE_TYPE__ size_t;
7
8 #define S2 "12"
9 #define S9 "123456789"
10
11 // <libint.h> functions.
12
13 char* gettext (const char *);
14
15 // <stdio.h> functions.
16
17 typedef struct FILE FILE;
18
19 int fputs (const char*, FILE*);
20 int fputs_unlocked (const char*, FILE*);
21
22 int puts (const char*);
23 int puts_unlocked (const char*);
24
25 // <string.h> functions.
26
27 void* memchr (const void*, int, size_t);
28 int memcmp (const void*, const void*, size_t);
29 void* memcpy (void*, const void*, size_t);
30 void* mempcpy (void*, const void*, size_t);
31 void* memmove (void*, const void*, size_t);
32
33 char* strchr (const char*, int);
34 char* strrchr (const char*, int);
35
36 int strcmp (const char*, const char*);
37 int strncmp (const char*, const char*, size_t);
38
39 char* strcat (char*, const char*);
40 char* stpcpy (char*, const char*);
41 char* strcpy (char*, const char*);
42 char* stpncpy (char*, const char*, size_t);
43 char* strncpy (char*, const char*, size_t);
44 char* strdup (const char*);
45 char* strndup (const char*, size_t);
46
47 char* strpbrk (const char*, const char*);
48 size_t strcspn (const char*, const char*);
49 size_t strspn (const char*, const char*);
50 char* strstr (const char*, const char*);
51
52 size_t strlen (const char*);
53 size_t strnlen (const char*, size_t);
54
55
56 extern void* malloc (size_t);
57
58 void sink (void*);
59
60
61 extern char *d;
62 extern char a0[0];
63
64 const char arr[7] = "abc\0def";
65
66 /* Unterminated array at the end of ARR above. */
67 #define unterm (arr + __builtin_strlen (arr) + 1)
68
69 /* Size of the unterminated array - 1. */
70 #define unterm_size (sizeof arr - __builtin_strlen (arr) - 1)
71
72 const void* nowarn_memchr (int x)
73 {
74 const char *p1 = unterm;
75 return memchr (p1, x, unterm_size);
76 }
77
78 const void* warn_memchr (int x)
79 {
80 const char *p1 = unterm;
81 return memchr (p1, x, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
82 }
83
84
85 void* nowarn_memcpy (void)
86 {
87 const char *s = unterm;
88 return memcpy (d, s, unterm_size);
89 }
90
91 void* warn_memcpy (void)
92 {
93 const char *s = unterm;
94 /* Use + 2 for an odd size to prevent the memmove --> MEM_REF transform
95 from defeating the warning (for now). */
96 return memcpy (d, s, unterm_size + 2 | 1); // { dg-warning "-Wstringop-overread" }
97 }
98
99
100 void* nowarn_mempcpy (void)
101 {
102 const char *s = unterm;
103 return mempcpy (d, s, unterm_size);
104 }
105
106 void* warn_mempcpy (void)
107 {
108 const char *s = unterm;
109 /* Use + 2 for an odd size to prevent the memmove --> MEM_REF transform
110 from defeating the warning (for now). */
111 return mempcpy (d, s, unterm_size + 2 | 1); // { dg-warning "-Wstringop-overread" }
112 }
113
114
115 void* nowarn_memmove (void)
116 {
117 const char *s = unterm;
118 return memmove (d, s, unterm_size);
119 }
120
121 void* warn_memmove (void)
122 {
123 const char *s = unterm;
124 /* Use + 2 for an odd size to prevent the memmove --> MEM_REF transform
125 from defeating the warning (for now). */
126 return memmove (d, s, unterm_size + 2); // { dg-warning "-Wstringop-overread" }
127 }
128
129
130 int nowarn_memcmp_1 (const char *p2)
131 {
132 const char *p1 = unterm;
133 return memcmp (p1, p2, unterm_size);
134 }
135
136 int warn_memcmp_1 (const char *p2)
137 {
138 const char *p1 = unterm;
139 return memcmp (p1, p2, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
140 }
141
142 int nowarn_memcmp_2 (const char *p1)
143 {
144 const char *p2 = unterm;
145 return memcmp (p1, p2, unterm_size);
146 }
147
148 int warn_memcmp_2 (const char *p1)
149 {
150 const char *p2 = unterm;
151 return memcmp (p1, p2, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
152 }
153
154
155 void warn_strcat (void)
156 {
157 strcat (d, unterm); // { dg-warning "-Wstringop-overread" }
158 }
159
160 void warn_strcat_a0 (void)
161 {
162 strcat (d, a0); // { dg-warning "-Wstringop-overread" }
163 }
164
165 void warn_strcat_end (void)
166 {
167 const char *s = arr + sizeof arr;
168 strcat (d, s); // { dg-warning "-Wstringop-overread" }
169 }
170
171 char* warn_stpcpy (void)
172 {
173 return stpcpy (d, unterm); // { dg-warning "-Wstringop-overread" }
174 }
175
176 char* warn_stpcpy_a0 (void)
177 {
178 return stpcpy (d, a0); // { dg-warning "-Wstringop-overread" }
179 }
180
181 char* warn_stpcpy_end (void)
182 {
183 const char *s = arr + sizeof arr;
184 return stpcpy (d, s); // { dg-warning "-Wstringop-overread" }
185 }
186
187 char* warn_stpcpy_malloc0 (void)
188 {
189 char *s = malloc (0);
190 sink (s);
191 return stpcpy (d, s); // { dg-warning "-Wstringop-overread" }
192 }
193
194
195 void warn_strcpy (void)
196 {
197 strcpy (d, unterm); // { dg-warning "-Wstringop-overread" }
198 }
199
200 void warn_strcpy_a0 (void)
201 {
202 strcpy (d, a0); // { dg-warning "-Wstringop-overread" }
203 }
204
205 void warn_strcpy_end (void)
206 {
207 const char *s = arr + sizeof arr;
208 strcpy (d, s); // { dg-warning "-Wstringop-overread" }
209 }
210
211 void warn_strcpy_malloc0 (void)
212 {
213 char *s = malloc (0);
214 sink (s);
215 strcpy (d, s); // { dg-warning "-Wstringop-overread" }
216 }
217
218
219 char* nowarn_stpncpy (void)
220 {
221 const char *s = unterm;
222 return stpncpy (d, s, unterm_size);
223 }
224
225 char* warn_stpncpy (void)
226 {
227 const char *s = unterm;
228 return stpncpy (d, s, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
229 }
230
231 char* warn_stpncpy_a0 (void)
232 {
233 return stpncpy (d, a0, 3); // { dg-warning "-Wstringop-overread" }
234 }
235
236 char* warn_stpncpy_end (void)
237 {
238 const char *s = arr + sizeof arr;
239 return stpncpy (d, s, sizeof arr); // { dg-warning "-Wstringop-overread" }
240 }
241
242
243 void nowarn_strncpy (void)
244 {
245 const char *s = unterm;
246 strncpy (d, s, unterm_size);
247 }
248
249 void warn_strncpy (void)
250 {
251 const char *s = unterm;
252 strncpy (d, s, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
253 }
254
255 void warn_strncpy_a0 (void)
256 {
257 const char *s = a0;
258 strncpy (d, s, sizeof arr); // { dg-warning "-Wstringop-overread" }
259 }
260
261 void warn_strncpy_end (void)
262 {
263 const char *s = arr + sizeof arr;
264 strncpy (d, s, sizeof arr); // { dg-warning "-Wstringop-overread" }
265 }
266
267
268 int warn_strlen (void)
269 {
270 return strlen (unterm); // { dg-warning "-Wstringop-overread" }
271 }
272
273 int warn_strlen_a0 (void)
274 {
275 return strlen (a0); // { dg-warning "-Wstringop-overread" }
276 }
277
278 int warn_strlen_end (void)
279 {
280 const char *s = arr + sizeof arr;
281 return strlen (s); // { dg-warning "-Wstringop-overread" }
282 }
283
284 int warn_strlen_malloc0 (void)
285 {
286 char *s = malloc (0);
287 sink (s);
288 return strlen (s); // { dg-warning "-Wstringop-overread" }
289 }
290
291
292 int nowarn_strnlen (void)
293 {
294 return strnlen (unterm, unterm_size);
295 }
296
297 int warn_strnlen (void)
298 {
299 return strnlen (unterm, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
300 }
301
302 int warn_strnlen_end (void)
303 {
304 const char *s = arr + sizeof arr;
305 return strnlen (s, 2); // { dg-warning "-Wstringop-overread" }
306 }
307
308
309 int warn_strcmp_1 (const char *s)
310 {
311 return strcmp (unterm, s); // { dg-warning "-Wstringop-overread" }
312 }
313
314 int warn_strcmp_2 (const char *s)
315 {
316 return strcmp (s, unterm); // { dg-warning "-Wstringop-overread" }
317 }
318
319 int warn_strcmp_2_end (const char *s)
320 {
321 const char *t = arr + sizeof arr;
322 return strcmp (s, t); // { dg-warning "-Wstringop-overread" }
323 }
324
325
326 int nowarn_strncmp_1 (const char *s2)
327 {
328 const char *s1 = unterm;
329 return strncmp (s1, s2, unterm_size);
330 }
331
332 int warn_strncmp_1 (const char *s2)
333 {
334 const char *s1 = unterm;
335 return strncmp (s1, s2, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
336 }
337
338 int nowarn_strncmp_2 (const char *s1)
339 {
340 const char *s2 = unterm;
341 return strncmp (s1, s2, unterm_size);
342 }
343
344 int warn_strncmp_2 (const char *s1)
345 {
346 const char *s2 = unterm;
347 return strncmp (s1, s2, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
348 }
349
350 int warn_strncmp_2_end (const char *s1)
351 {
352 const char *s2 = arr + sizeof arr;;
353 return strncmp (s1, s2, sizeof arr); // { dg-warning "-Wstringop-overread" }
354 }
355
356
357 int nowarn_strncmp_1_s2 (void)
358 {
359 /* Since the read is also bounded by the length of the S2 literal
360 and so safe, expect no warning. */
361 const char *s = unterm;
362 return strncmp (s, S2, unterm_size + 1); // { dg-bogus "-Wstringop-overread" "pr101778" { xfail *-*-* } }
363 }
364
365 int warn_strncmp_2_s2 (void)
366 {
367 /* Same as above. */
368 const char *t = unterm;
369 return strncmp (S2, t, unterm_size + 1); // { dg-bogus "-Wstringop-overread" "pr101778" { xfail *-*-* } }
370 }
371
372
373 int warn_strncmp_1_s9 (void)
374 {
375 /* Since both the bound and the length of the S9 literal are greater
376 than the size of UNNTERM the call reads past the end of the array.
377 Expect a warning. */
378 const char *s1 = unterm;
379 return strncmp (s1, S9, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
380 }
381
382 int warn_strncmp_2_s9 (void)
383 {
384 /* Same as above. */
385 const char *s2 = unterm;
386 return strncmp (S9, s2, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
387 }
388
389
390 const char* warn_strchr (int x)
391 {
392 return strchr (unterm, x); // { dg-warning "-Wstringop-overread" }
393 }
394
395 const char* warn_strchr_end (int x)
396 {
397 const char *s = arr + sizeof arr;
398 return strchr (s, x); // { dg-warning "-Wstringop-overread" }
399 }
400
401
402 const char* warn_strrchr (int x)
403 {
404 return strrchr (unterm, x); // { dg-warning "-Wstringop-overread" }
405 }
406
407 const char* warn_strrchr_end (int x)
408 {
409 const char *s = arr + sizeof arr;
410 return strrchr (s, x); // { dg-warning "-Wstringop-overread" }
411 }
412
413
414 char* warn_strdup (void)
415 {
416 return strdup (unterm); // { dg-warning "-Wstringop-overread" }
417 }
418
419 char* warn_strdup_end (void)
420 {
421 const char *s = arr + sizeof arr;
422 return strdup (s); // { dg-warning "-Wstringop-overread" }
423 }
424
425
426 char* nowarn_strndup (void)
427 {
428 return strndup (unterm, unterm_size);
429 }
430
431 char* warn_strndup (void)
432 {
433 return strndup (unterm, unterm_size + 1); // { dg-warning "-Wstringop-overread" }
434 }
435
436 char* warn_strndup_end (void)
437 {
438 const char *s = arr + sizeof arr;
439 return strndup (s, sizeof arr); // { dg-warning "-Wstringop-overread" }
440 }
441
442
443 const char* warn_strpbrk_1 (const char *s2)
444 {
445 return strpbrk (unterm, s2); // { dg-warning "-Wstringop-overread" }
446 }
447
448 const char* warn_strpbrk_2 (const char *s1)
449 {
450 return strpbrk (s1, unterm); // { dg-warning "-Wstringop-overread" }
451 }
452
453
454 size_t warn_strspn_1 (const char *s2)
455 {
456 return strspn (unterm, s2); // { dg-warning "-Wstringop-overread" }
457 }
458
459 size_t warn_strspn_1_end (const char *s2)
460 {
461 const char *s1 = arr + sizeof arr;
462 return strspn (s1, s2); // { dg-warning "-Wstringop-overread" }
463 }
464
465 size_t warn_strspn_2 (const char *s1)
466 {
467 return strspn (s1, unterm); // { dg-warning "-Wstringop-overread" }
468 }
469
470 size_t warn_strspn_2_end (const char *s1)
471 {
472 const char *s2 = arr + sizeof arr;
473 return strspn (s1, s2); // { dg-warning "-Wstringop-overread" }
474 }
475
476
477 size_t warn_strcspn_1 (const char *s2)
478 {
479 return strcspn (unterm, s2); // { dg-warning "-Wstringop-overread" }
480 }
481
482 size_t warn_strcspn_1_end (const char *s2)
483 {
484 const char *s1 = arr + sizeof arr;
485 return strcspn (s1, s2); // { dg-warning "-Wstringop-overread" }
486 }
487
488 size_t warn_strcspn_2 (const char *s1)
489 {
490 return strcspn (s1, unterm); // { dg-warning "-Wstringop-overread" }
491 }
492
493 size_t warn_strcspn_2_end (const char *s1)
494 {
495 const char *s2 = arr + sizeof arr;
496 return strcspn (s1, s2); // { dg-warning "-Wstringop-overread" }
497 }
498
499
500 const char* warn_strstr_1 (const char *s2)
501 {
502 return strstr (unterm, s2); // { dg-warning "-Wstringop-overread" }
503 }
504
505 const char* warn_strstr_1_end (const char *s2)
506 {
507 const char *s1 = arr + sizeof arr;
508 return strstr (s1, s2); // { dg-warning "-Wstringop-overread" }
509 }
510
511
512 const char* warn_strstr_2 (const char *s1)
513 {
514 return strstr (s1, unterm); // { dg-warning "-Wstringop-overread" }
515 }
516
517 const char* warn_strstr_2_end (const char *s1)
518 {
519 const char *s2 = arr + sizeof arr;
520 return strstr (s1, s2); // { dg-warning "-Wstringop-overread" }
521 }
522
523
524 void warn_puts (void)
525 {
526 puts (unterm); // { dg-warning "-Wstringop-overread" }
527 }
528
529 void warn_puts_end (void)
530 {
531 const char *s = arr + sizeof arr;
532 puts (s); // { dg-warning "-Wstringop-overread" }
533 }
534
535
536 void warn_fputs (FILE *f)
537 {
538 fputs (unterm, f); // { dg-warning "-Wstringop-overread" }
539 }
540
541 void warn_fputs_end (FILE *f)
542 {
543 const char *s = arr + sizeof arr;
544 fputs (s, f); // { dg-warning "-Wstringop-overread" }
545 }
546
547
548 void warn_puts_unlocked (void)
549 {
550 puts_unlocked (unterm); // { dg-warning "-Wstringop-overread" }
551 }
552
553 void warn_puts_unlocked_end (void)
554 {
555 const char *s = arr + sizeof arr;
556 puts_unlocked (s); // { dg-warning "-Wstringop-overread" }
557 }
558
559 void warn_fputs_unlocked (FILE *f)
560 {
561 fputs_unlocked (unterm, f); // { dg-warning "-Wstringop-overread" }
562 }
563
564
565 const char* warn_gettext (void)
566 {
567 return gettext (unterm); // { dg-warning "-Wstringop-overread" }
568 }
569
570 const char* warn_gettext_end (void)
571 {
572 const char *s = arr + sizeof arr;
573 return gettext (s); // { dg-warning "-Wstringop-overread" }
574 }