131
|
1 /* Test to exercise that -Warray-bounds warnings for memory and string
|
|
2 functions are issued even when they are declared in system headers
|
|
3 (i.e., not just when they are explicitly declared in the source
|
|
4 file.)
|
|
5 Also verify that the warnings are issued even for calls where the
|
|
6 source of the excessive array bound is in a different function than
|
|
7 the call.
|
|
8 { dg-do compile }
|
|
9 { dg-options "-O2 -Warray-bounds -Wno-stringop-overflow" } */
|
|
10
|
|
11 #include <stddef.h>
|
|
12 #include <string.h>
|
|
13
|
|
14 #undef memcpy
|
|
15 #undef strcpy
|
|
16 #undef strncpy
|
|
17
|
|
18 #define MAX (__SIZE_MAX__ / 2)
|
|
19
|
|
20 void sink (void*);
|
|
21
|
|
22 struct __attribute__ ((packed)) Array
|
|
23 {
|
|
24 char a13[13];
|
|
25 char a15[15];
|
|
26 char a17[17];
|
|
27 };
|
|
28
|
|
29 /* Exercise memcpy out-of-bounds offsets with an array of known size. */
|
|
30
|
|
31 static void
|
|
32 wrap_memcpy_src_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
|
|
33 {
|
|
34 memcpy (d, s + i, n); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar. with type .(struct )?Array." "memcpy" } */
|
|
35 }
|
|
36
|
|
37 void call_memcpy_src_xsize (char *d, size_t n)
|
|
38 {
|
|
39 struct Array ar;
|
|
40 sink (&ar);
|
|
41 wrap_memcpy_src_xsize (d, ar.a13, 46, n);
|
|
42 sink (&ar);
|
|
43 }
|
|
44
|
|
45 /* Exercise memcpy out-of-bounds offsets with an array of unknown size. */
|
|
46
|
|
47 static void
|
|
48 wrap_memcpy_src_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
|
|
49 {
|
|
50 memcpy (d, s + i, n); /* { dg-warning "pointer overflow between offset \[0-9\]+ and size 3" "memcpy" } */
|
|
51 }
|
|
52
|
|
53 void call_memcpy_src_diff_max (char *d, const char *s, size_t n)
|
|
54 {
|
|
55 wrap_memcpy_src_diff_max (d, s, MAX, 3);
|
|
56 }
|
|
57
|
|
58 static void
|
|
59 wrap_memcpy_dst_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
|
|
60 {
|
|
61 memcpy (d + i, s, n); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar1. with type .(struct )?Array." "memcpy" } */
|
|
62 }
|
|
63
|
|
64 void call_memcpy_dst_xsize (const char *s, size_t n)
|
|
65 {
|
|
66 struct Array ar1; /* { dg-message ".ar1. declared here" } */
|
|
67 sink (&ar1);
|
|
68 wrap_memcpy_dst_xsize (ar1.a15, s, 34, n);
|
|
69 sink (&ar1);
|
|
70 }
|
|
71
|
|
72 static void
|
|
73 wrap_memcpy_dst_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
|
|
74 {
|
|
75 memcpy (d + i, s, n); /* { dg-warning "offset -?\[0-9\]+ is out of the bounds \\\[0, 45] of object .ar2. with type .(struct )?Array." "memcpy" } */
|
|
76 }
|
|
77
|
|
78 void call_memcpy_dst_diff_max (const char *s, size_t n)
|
|
79 {
|
|
80 struct Array ar2; /* { dg-message ".ar2. declared here" } */
|
|
81 sink (&ar2);
|
|
82 wrap_memcpy_dst_diff_max (ar2.a15, s, MAX, n);
|
|
83 sink (&ar2);
|
|
84 }
|
|
85
|
|
86
|
|
87 static void wrap_strcat_src_xsize (char *d, const char *s, ptrdiff_t i)
|
|
88 {
|
|
89 strcat (d, s + i); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar3. with type .(struct )?Array." "strcat" } */
|
|
90 }
|
|
91
|
|
92 void call_strcat_src_xsize (char *d)
|
|
93 {
|
|
94 struct Array ar3; /* { dg-message ".ar3. declared here" } */
|
|
95 sink (&ar3);
|
|
96 wrap_strcat_src_xsize (d, ar3.a15, 15 + 17 + 1);
|
|
97 sink (&ar3);
|
|
98 }
|
|
99
|
|
100 static void wrap_strcat_dst_xsize (char *d, const char *s, ptrdiff_t i)
|
|
101 {
|
|
102 strcat (d + i, s); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar4. with type .(struct )?Array." "strcat" } */
|
|
103 }
|
|
104
|
|
105 void call_strcat_dst_xsize (const char *s)
|
|
106 {
|
|
107 struct Array ar4; /* { dg-message ".ar4. declared here" } */
|
|
108 sink (&ar4);
|
|
109 wrap_strcat_dst_xsize (ar4.a15, s, 15 + 17 + 2);
|
|
110 sink (&ar4);
|
|
111 }
|
|
112
|
|
113
|
|
114 static void wrap_strcpy_src_xsize (char *d, const char *s, ptrdiff_t i)
|
|
115 {
|
|
116 strcpy (d, s + i); /* { dg-warning "offset 48 is out of the bounds \\\[0, 45] of object .ar5. with type .(struct )?Array." "strcpy" } */
|
|
117 }
|
|
118
|
|
119 void call_strcpy_src_xsize (char *d)
|
|
120 {
|
|
121 struct Array ar5; /* { dg-message ".ar5. declared here" } */
|
|
122 sink (&ar5);
|
|
123 wrap_strcpy_src_xsize (d, ar5.a15, 15 + 17 + 3);
|
|
124 sink (&ar5);
|
|
125 }
|
|
126
|
|
127 static void wrap_strcpy_dst_xsize (char *d, const char *s, ptrdiff_t i)
|
|
128 {
|
|
129 strcpy (d + i, s); /* { dg-warning "offset 49 is out of the bounds \\\[0, 45] of object .ar6. with type .(struct )?Array." "strcpy" } */
|
|
130 }
|
|
131
|
|
132 void call_strcpy_dst_xsize (const char *s)
|
|
133 {
|
|
134 struct Array ar6; /* { dg-message ".ar6. declared here" } */
|
|
135 sink (&ar6);
|
|
136 wrap_strcpy_dst_xsize (ar6.a15, s, 15 + 17 + 4);
|
|
137 sink (&ar6);
|
|
138 }
|
|
139
|
|
140
|
|
141 /* Exercise strncpy out-of-bounds offsets with an array of known size. */
|
|
142
|
|
143 static void
|
|
144 wrap_strncpy_src_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
|
|
145 {
|
|
146 strncpy (d, s + i, n); /* { dg-warning "offset 46 is out of the bounds \\\[0, 45] of object .ar7. with type '(struct )?Array." "strncpy" } */
|
|
147 }
|
|
148
|
|
149 void call_strncpy_src_xsize (char *d, size_t n)
|
|
150 {
|
|
151 struct Array ar7; /* { dg-message ".ar7. declared here" } */
|
|
152 sink (&ar7);
|
|
153 wrap_strncpy_src_xsize (d, ar7.a17, 17 + 1, n);
|
|
154 sink (&ar7);
|
|
155 }
|
|
156
|
|
157 /* Exercise strncpy out-of-bounds offsets with an array of unknown size. */
|
|
158
|
|
159 static void
|
|
160 wrap_strncpy_src_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
|
|
161 {
|
|
162 /* Unlike in the similar call to memcpy(), there is no pointer
|
|
163 overflow here because the size N is not added to the source
|
|
164 offset. */
|
|
165 strncpy (d, s + i, n);
|
|
166 }
|
|
167
|
|
168 void call_strncpy_src_diff_max (char *d, const char *s, size_t n)
|
|
169 {
|
|
170 wrap_strncpy_src_diff_max (d, s, MAX, 3);
|
|
171 }
|
|
172
|
|
173 static void
|
|
174 wrap_strncpy_dst_xsize (char *d, const char *s, ptrdiff_t i, size_t n)
|
|
175 {
|
|
176 strncpy (d + i, s, n); /* { dg-warning "offset 47 is out of the bounds \\\[0, 45] of object .ar8. with type .(struct )?Array." "strncpy" } */
|
|
177 }
|
|
178
|
|
179 void call_strncpy_dst_xsize (const char *s, size_t n)
|
|
180 {
|
|
181 struct Array ar8; /* { dg-message ".ar8. declared here" } */
|
|
182 sink (&ar8);
|
|
183 wrap_strncpy_dst_xsize (ar8.a17, s, 17 + 2, n);
|
|
184 sink (&ar8);
|
|
185 }
|
|
186
|
|
187 static void
|
|
188 wrap_strncpy_dst_diff_max (char *d, const char *s, ptrdiff_t i, size_t n)
|
|
189 {
|
|
190 strncpy (d + i, s, n); /* { dg-warning "offset -\[0-9\]+ is out of the bounds \\\[0, 45] of object .ar9. with type .(struct )?Array." "strncpy" } */
|
|
191 }
|
|
192
|
|
193 void call_strncpy_dst_diff_max (const char *s, size_t n)
|
|
194 {
|
|
195 struct Array ar9; /* { dg-message ".ar9. declared here" "strncpy" } */
|
|
196 sink (&ar9);
|
|
197 wrap_strncpy_dst_diff_max (ar9.a17, s, MAX, n);
|
|
198 sink (&ar9);
|
|
199 }
|
|
200
|
|
201 static void
|
|
202 wrap_strncpy_dstarray_diff_neg (char *d, const char *s, ptrdiff_t i, size_t n)
|
|
203 {
|
|
204 strncpy (d + i, s, n); /* { dg-warning "offset -\[0-9\]+ is out of the bounds \\\[0, 90] of object .ar10. with type .(struct )?Array ?\\\[2]." "strncpy" } */
|
|
205 }
|
|
206
|
|
207 void call_strncpy_dstarray_diff_neg (const char *s, size_t n)
|
|
208 {
|
|
209 struct Array ar10[2]; /* { dg-message ".ar10. declared here" } */
|
|
210 sink (&ar10);
|
|
211
|
|
212 int off = (char*)ar10[1].a17 - (char*)ar10 + 1;
|
|
213 wrap_strncpy_dstarray_diff_neg (ar10[1].a17, s, -off, n);
|
|
214
|
|
215 sink (&ar10);
|
|
216 }
|
|
217
|
|
218 /* { dg-prune-output "outside array bounds" } */
|