]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/testsuite/gcc.dg/Wstringop-overflow-50.c
Update copyright years.
[thirdparty/gcc.git] / gcc / testsuite / gcc.dg / Wstringop-overflow-50.c
CommitLineData
83685efd
MS
1/* Verify that writes at excessive offsets into objects of unknown size
2 pointed to by function arguments are diagnosed.
3 { dg-do compile }
4 { dg-options "-O2" } */
5
6#define DIFF_MAX __PTRDIFF_MAX__
7
8typedef __PTRDIFF_TYPE__ ptrdiff_t;
9typedef __SIZE_TYPE__ size_t;
10
11void* memset (void*, int, size_t);
12
13void sink (void*);
14
15char* fcall (void);
16
17void char_ptr_cst_off_cst_size (char *p)
18 // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'p'" "note" { target *-*-* } .-1 }
19{
20 size_t idx = DIFF_MAX - 3;
21
22 memset (p + idx, 0, 3);
23 sink (p);
24
25 ++idx;
26 memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 2" }
27 sink (p);
28
29 ++idx;
30 memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 1" }
31
32 ++idx;
33 memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 0" }
34}
35
36
37void char_ptr_var_difoff_cst_size (ptrdiff_t idx)
38{
39 char *p = fcall ();
40 /* The offset is a range with a very large lower bound and an upper
41 bound of DIFF_MAX. There's not point in also mentioning the latter
42 (it wouldn't make the note any more meaningful) so verify it only
43 mentions the lower bound.
44 { dg-message "at offset \\d+ into destination object of size \\\[0, \\d+] (allocated|returned) by 'fcall'" "note" { target *-*-* } .-5 } */
45
46 if (idx < DIFF_MAX - 3)
47 idx = DIFF_MAX - 3;
48
49 memset (p + idx, 0, 3);
50 sink (p);
51
52 memset (p + idx, 0, 5); // { dg-warning "writing 5 bytes into a region of size 3" }
53}
54
55
56void char_ptr_var_szoff_cst_size (size_t idx)
57{
58 extern char* gptr;
59 // { dg-message "at offset \\d+ into destination object 'gptr'" "note" { target *-*-* } .-1 }
60
61 char *p = gptr;
62
63 if (idx < DIFF_MAX - 3)
64 idx = DIFF_MAX - 3;
65
66 memset (p + idx, 0, 3);
67 sink (p);
68
69 memset (p + idx, 0, 5); // { dg-warning "writing 5 bytes into a region of size 3" "" { xfail *-*-* } }
70
71 if (idx > DIFF_MAX)
72 idx = DIFF_MAX;
73
74 memset (p + idx, 0, 7); // { dg-warning "writing 7 bytes into a region of size 3" }
75}
76
77
78void char_ptr_var_difoff_var_size (char *p, ptrdiff_t idx, size_t n)
79 // { dg-message "at offset \\d+ into destination object 'p'" "note" { target *-*-* } .-1 }
80{
81 if (idx < DIFF_MAX - 3)
82 idx = DIFF_MAX - 3;
83
84 if (n < 3 || 7 < n)
85 n = 3;
86
87 memset (p + idx, 0, n);
88 sink (p);
89
90 ++n;
91 memset (p + idx, 0, n); // { dg-warning "writing between 4 and 8 bytes into a region of size 3" }
92}
93
94
95void char_ptr_var_szoff_var_size (char *p, size_t idx, size_t n)
96 // { dg-message "at offset \\\[\[1-9\]\[0-9\]+, \[1-9\]\[0-9\]+] into destination object 'p'" "note" { xfail *-*-* } .-1 }
97{
98 if (idx < DIFF_MAX - 3)
99 idx = DIFF_MAX - 3;
100
101 if (n < 3 || 7 < n)
102 n = 3;
103
104 memset (p + idx, 0, n);
105 sink (p);
106
107 ++n;
108 /* With an unsigned offset large values are interpreted as negative
109 so the addition (p + idx) is effectively treated as subtraction,
110 making an overflow indistinguishable from a valid (if unlikely)
111 store. */
112 memset (p + idx, 0, n); // { dg-warning "writing between 4 and 8 bytes into a region of size 3" "pr?????" { xfail *-*-* } }
113}
114
115
116void int_ptr_cst_off_cst_size (int *p)
117 // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'p'" "note" { target *-*-* } .-1 }
118{
119 size_t idx = DIFF_MAX / sizeof *p;
120
121 memset (p + idx, 0, 3);
122 sink (p);
123
124 memset (p + idx, 0, 5); // { dg-warning "writing 5 bytes into a region of size 3" }
125}