Mercurial > hg > CbC > CbC_gcc
comparison gcc/testsuite/c-c++-common/Warray-bounds-3.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Exercise that -Warray-bounds is issued for out-of-bounds offsets | |
2 in calls to built-in functions. | |
3 { dg-do compile } | |
4 { dg-options "-O2 -Wno-stringop-overflow -Warray-bounds -ftrack-macro-expansion=0" } */ | |
5 | |
6 #include "../gcc.dg/range.h" | |
7 | |
8 #if __cplusplus | |
9 # define restrict __restrict | |
10 extern "C" { | |
11 #endif | |
12 | |
13 extern void* memcpy (void* restrict, const void* restrict, size_t); | |
14 extern void* mempcpy (void* restrict, const void* restrict, size_t); | |
15 extern void* memmove (void*, const void*, size_t); | |
16 | |
17 extern char* stpcpy (char* restrict, const char* restrict); | |
18 | |
19 extern char* strcat (char* restrict, const char* restrict); | |
20 extern char* strcpy (char* restrict, const char* restrict); | |
21 extern char* strncpy (char* restrict, const char* restrict, size_t); | |
22 | |
23 #if __cplusplus | |
24 } /* extern "C" */ | |
25 #endif | |
26 | |
27 void sink (void*, ...); | |
28 | |
29 #define CAT(x, y) x ## y | |
30 #define CONCAT(x, y) CAT (x, y) | |
31 #define UNIQUE_NAME(x) CONCAT(x, __LINE__) | |
32 | |
33 #define T(type, N, dst, src, n) do { \ | |
34 extern type UNIQUE_NAME (a)[N]; \ | |
35 type *a = UNIQUE_NAME (a); \ | |
36 type *pd = (dst); \ | |
37 const type *ps = (src); \ | |
38 FUNC (pd, ps, n); \ | |
39 sink (a, pd, ps); \ | |
40 } while (0) | |
41 | |
42 | |
43 void test_memcpy_bounds (char *d, const char *s, size_t n) | |
44 { | |
45 #define FUNC memcpy | |
46 | |
47 /* Verify that invalid offsets into an array of known size are | |
48 detected. */ | |
49 | |
50 T (char, 1, a + SR (DIFF_MIN, -1), s, n); /* { dg-warning "offset \\\[-\[0-9\]+, -1] is out of the bounds \\\[0, 1] of object \[^\n\r]* with type .char ?\\\[1]" } */ | |
51 T (char, 1, a + SR (-2, -1), s, n); /* { dg-warning "offset \\\[-2, -1] is out of the bounds \\\[0, 1] of object" } */ | |
52 T (char, 1, a + SR (-2, 0), s, n); | |
53 | |
54 T (char, 1, a + UR (0, 1), s, n); | |
55 T (char, 1, a + UR (0, 2), s, n); | |
56 T (char, 1, a + UR (1, 2), s, n); | |
57 T (char, 1, a + UR (2, 3), s, n); /* { dg-warning "offset \\\[2, 3] is out of the bounds \\\[0, 1] of object " } */ | |
58 T (char, 1, a + UR (2, DIFF_MAX), s, n); /* { dg-warning "offset \\\[2, \[0-9\]+] is out of the bounds \\\[0, 1] of object " "memcpy" } */ | |
59 | |
60 /* Offsets in excess of DIFF_MAX are treated as negative even if | |
61 they appear as large positive in the source. It would be nice | |
62 if they retained their type but unfortunately that's not how | |
63 it works so be prepared for both in case it even gets fixed. */ | |
64 T (char, 1, a + UR (3, SIZE_MAX - 1), s, n); /* { dg-warning "offset \\\[3, -?\[0-9\]+] is out of the bounds \\\[0, 1] of object" "memcpy" } */ | |
65 | |
66 /* Verify that invalid offsets into an array of unknown size are | |
67 detected. */ | |
68 extern char arr[]; | |
69 T (char, 1, arr + SR (DIFF_MIN, 0), s, n); | |
70 T (char, 1, arr + SR (DIFF_MIN + 1, -1), s, n); /* { dg-warning "offset \\\[-\[0-9\]+, -1] is out of the bounds of object " "memcpy" } */ | |
71 T (char, 1, arr + SR (DIFF_MIN, 1), s, n); | |
72 T (char, 1, arr + SR (DIFF_MIN, DIFF_MAX), s, n); | |
73 T (char, 1, arr + SR ( -2, -1), s, n); /* { dg-warning "offset \\\[-2, -1] is out of the bounds of object " "memcpy" } */ | |
74 T (char, 1, arr + SR ( -1, 0), s, n); | |
75 T (char, 1, arr + SR ( -1, 1), s, n); | |
76 T (char, 1, arr + SR ( -1, DIFF_MAX - 1), s, n); | |
77 T (char, 1, arr + SR ( 0, 1), s, n); | |
78 T (char, 1, arr + SR ( 0, DIFF_MAX - 1), s, n); | |
79 T (char, 1, arr + SR ( 1, 2), s, n); | |
80 T (char, 1, arr + SR ( 1, DIFF_MAX - 1), s, n); | |
81 | |
82 /* Verify that all offsets via a pointer to an uknown object are | |
83 accepted. */ | |
84 | |
85 /* Negative indices between [DIFF_MIN, DIFF_MAX] are valid since | |
86 the pointer to which the offset is applied can be at a positive | |
87 offset from the beginning of an object. */ | |
88 T (char, 1, d + SR (DIFF_MIN, 0), s, n); | |
89 T (char, 1, d + SR (DIFF_MIN, -1), s, n); | |
90 T (char, 1, d + SR (DIFF_MIN, 1), s, n); | |
91 T (char, 1, d + SR (DIFF_MIN, DIFF_MAX - 1), s, n); | |
92 T (char, 1, d + SR ( -2, -1), s, n); | |
93 T (char, 1, d + SR ( -1, 0), s, n); | |
94 T (char, 1, d + SR ( -1, 1), s, n); | |
95 T (char, 1, d + SR ( -1, DIFF_MAX - 1), s, n); | |
96 T (char, 1, d + SR ( 0, 1), s, n); | |
97 T (char, 1, d + SR ( 0, DIFF_MAX - 1), s, n); | |
98 T (char, 1, d + SR ( 1, 2), s, n); | |
99 T (char, 1, d + SR ( 1, DIFF_MAX - 1), s, n); | |
100 } | |
101 | |
102 /* Verify offsets in an anti-range. */ | |
103 | |
104 void test_memcpy_bounds_anti_range (char *d, const char *s, size_t n) | |
105 { | |
106 T (char, 9, a, a + SAR (-2, -1), 3); | |
107 T (char, 9, a, a + SAR (-1, 1), 3); | |
108 T (char, 9, a, a + SAR ( 0, 1), 3); | |
109 T (char, 9, a, a + SAR ( 0, 2), 3); | |
110 T (char, 9, a, a + SAR ( 0, 3), 3); | |
111 T (char, 9, a, a + SAR ( 0, 4), 3); | |
112 T (char, 9, a, a + SAR ( 0, 5), 3); | |
113 /* The initial source range is valid but the final range after the access | |
114 has complete cannot be. The value mentioned in the warning is the final | |
115 offset, i.e., 7 + 3. Including the whole final range because would be | |
116 confusing (the upper bound would either be negative or a very large | |
117 positive number) so only the lower bound is included. */ | |
118 T (char, 9, a, a + SAR ( 0, 6), 3); /* { dg-warning "forming offset 10 is out of the bounds \\\[0, 9] of object " "memcpy" } */ | |
119 | |
120 /* This fails because the offset isn't represented as an SSA_NAME | |
121 but rather as a GIMPLE_PHI (offset, 0). With some effort it is | |
122 possible to extract the range from the PHI but it's not implemented | |
123 (yet). */ | |
124 T (char, 9, a, a + SAR ( 1, 6), 3); /* { dg-warning "forming offset \\\[9, 0] is out of the bounds \\\[0, 9] of object " "memcpy" { xfail *-*-* } } */ | |
125 | |
126 /* The range of offsets is the union of [0, 1] and [7, PTRDIFF_MAX] | |
127 of which the first subrange is valid and thus no warming for memcpy | |
128 is issued. Similarly for the next test. */ | |
129 T (char, 9, a, a + SAR ( 2, 6), 3); | |
130 T (char, 9, a, a + SAR ( 3, 6), 3); | |
131 | |
132 T (char, 9, a, a + SAR (-1, 7), 3); /* { dg-warning "forming offset \\\[10, 11] is out of the bounds \\\[0, 9] of object " "memcpy" } */ | |
133 T (char, 9, a, a + SAR (-2, 8), 3); /* { dg-warning "forming offset \\\[10, 12] is out of the bounds \\\[0, 9] of object " "memcpy" } */ | |
134 T (char, 9, a, a + SAR (-3, 7), 5); /* { dg-warning "forming offset \\\[10, 13] is out of the bounds \\\[0, 9] of object " "memcpy" } */ | |
135 | |
136 T (char, 9, a + SAR (-2, -1), a, 3); | |
137 T (char, 9, a + SAR (-1, 1), a, 3); | |
138 T (char, 9, a + SAR ( 0, 1), a, 3); | |
139 T (char, 9, a + SAR ( 0, 2), a, 3); | |
140 T (char, 9, a + SAR ( 0, 3), a, 3); | |
141 T (char, 9, a + SAR ( 0, 6), a, 3); /* { dg-warning "forming offset 10 is out of the bounds \\\[0, 9] of object " "memcpy" } */ | |
142 T (char, 9, a + SAR (-1, 7), a, 3); /* { dg-warning "forming offset \\\[10, 11] is out of the bounds \\\[0, 9] of object " "memcpy" } */ | |
143 T (char, 9, a + SAR (-2, 8), a, 3); /* { dg-warning "forming offset \\\[10, 12] is out of the bounds \\\[0, 9] of object " "memcpy" } */ | |
144 | |
145 ptrdiff_t i = SAR (DIFF_MIN + 1, DIFF_MAX - 4); | |
146 T (char, 1, d, d + SAR (DIFF_MIN + 3, DIFF_MAX - 1), 3); | |
147 T (char, 1, d, d + SAR (DIFF_MIN + 3, DIFF_MAX - 3), 5); | |
148 } | |
149 | |
150 /* Verify that pointer overflow in the computation done by memcpy | |
151 (i.e., offset + size) is detected and diagnosed. */ | |
152 | |
153 void test_memcpy_overflow (char *d, const char *s, size_t n) | |
154 { | |
155 extern char arr[]; | |
156 | |
157 /* Verify that offset overflow involving an array of unknown size | |
158 but known access size is detected. This works except with small | |
159 sizes that are powers of 2 due to bug . */ | |
160 T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 1); | |
161 T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 2); /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 2 accessing array " "bug " { xfail *-*-* } } */ | |
162 T (char, 1, arr + SR (DIFF_MAX - 2, DIFF_MAX), s, 3); /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 3 accessing array " "memcpy" } */ | |
163 T (char, 1, arr + SR (DIFF_MAX - 4, DIFF_MAX), s, 5); /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 5 accessing array " "memcpy" } */ | |
164 } | |
165 | |
166 void test_memcpy_bounds_memarray_range (void) | |
167 { | |
168 #undef TM | |
169 #define TM(mem, dst, src, n) \ | |
170 do { \ | |
171 struct MA { char a5[5]; int i; } ma; \ | |
172 sink (&ma); /* Initialize arrays. */ \ | |
173 memcpy (dst, src, n); \ | |
174 sink (&ma); \ | |
175 } while (0) | |
176 | |
177 ptrdiff_t i = SR (1, 2); | |
178 | |
179 TM (ma.a5, ma.a5 + i, ma.a5, 1); | |
180 TM (ma.a5, ma.a5 + i, ma.a5, 3); | |
181 TM (ma.a5, ma.a5 + i, ma.a5, 5); | |
182 TM (ma.a5, ma.a5 + i, ma.a5, 7); /* diagnosed with -Warray-bounds=2 */ | |
183 } | |
184 | |
185 void test_memmove_bounds (char *d, const char *s, size_t n) | |
186 { | |
187 #undef FUNC | |
188 #define FUNC memmove | |
189 | |
190 T (char, 1, a + SR (DIFF_MIN + 1, -1), s, n); /* { dg-warning "offset \\\[-\[0-9\]+, -1] is out of the bounds \\\[0, 1] of object \[^\n\r]+ with type .char ?\\\[1]" } */ | |
191 T (char, 1, a + SR (-2, -1), s, n); /* { dg-warning "offset \\\[-2, -1] is out of the bounds \\\[0, 1] of object" } */ | |
192 T (char, 1, a + SR (-2, 0), s, n); | |
193 | |
194 const int *pi = (const int*)s; | |
195 T (int, 2, a + SR (-1, 1), pi, n); | |
196 T (int, 2, a + SR (-1, 2), pi, n); | |
197 T (int, 2, a + SR ( 0, 2), pi, n); | |
198 T (int, 2, a + SR ( 0, 3), pi, n); | |
199 T (int, 2, a + SR ( 1, 3), pi, n); | |
200 T (int, 2, a + SR ( 2, 3), pi, n); | |
201 | |
202 const int32_t *pi32 = (const int32_t*)s; | |
203 T (int32_t, 2, a + SR ( 3, 4), pi32, n); /* { dg-warning "offset \\\[12, 16] is out of the bounds \\\[0, 8] of object .\[^\n\r]+. with type .int32_t ?\\\[2]." } */ | |
204 } | |
205 | |
206 | |
207 void test_mempcpy_bounds (char *d, const char *s, size_t n) | |
208 { | |
209 #undef FUNC | |
210 #define FUNC mempcpy | |
211 | |
212 /* Verify that invalid offsets into an array of known size are | |
213 detected. */ | |
214 | |
215 T (char, 1, a + SR (DIFF_MIN, -1), s, n); /* { dg-warning "offset \\\[-\[0-9\]+, -1] is out of the bounds" "mempcpy" } */ | |
216 T (char, 1, a + SR (-2, -1), s, n); /* { dg-warning "offset \\\[-2, -1] is out of the bounds" "mempcpy" } */ | |
217 T (char, 1, a + SR (-2, 0), s, n); | |
218 | |
219 T (char, 1, a + UR (0, 1), s, n); | |
220 T (char, 1, a + UR (0, 2), s, n); | |
221 T (char, 1, a + UR (1, 2), s, n); | |
222 T (char, 1, a + UR (2, 3), s, n); /* { dg-warning "offset \\\[2, 3] is out of the bounds \\\[0, 1] of object " "mempcpy" } */ | |
223 T (char, 1, a + UR (2, DIFF_MAX), s, n); /* { dg-warning "offset \\\[2, \[0-9\]+] is out of the bounds \\\[0, 1] of object" "mempcpy" } */ | |
224 | |
225 /* Offsets in excess of DIFF_MAX are treated as negative even if | |
226 they appear as large positive in the source. It would be nice | |
227 if they retained their type but unfortunately that's not how | |
228 it works so be prepared for both in case it ever gets fixed. */ | |
229 T (char, 1, a + UR (3, SIZE_MAX), s, n); /* { dg-warning "offset \\\[3, -?\[0-9\]+] is out of the bounds \\\[0, 1] of object " "mempcpy" } */ | |
230 | |
231 /* Verify that invalid offsets into an array of unknown size are | |
232 detected. */ | |
233 extern char arr[]; | |
234 T (char, 1, arr + SR (DIFF_MIN, 0), s, n); | |
235 T (char, 1, arr + SR (DIFF_MIN, -1), s, n); /* { dg-warning "offset \\\[-\[0-9\]+, -1] is out of the bounds of object" "mempcpy" } */ | |
236 T (char, 1, arr + SR (DIFF_MIN, 1), s, n); | |
237 T (char, 1, arr + SR (DIFF_MIN, DIFF_MAX), s, n); | |
238 T (char, 1, arr + SR ( -2, -1), s, n); /* { dg-warning "offset \\\[-2, -1] is out of the bounds of object" "mempcpy" } */ | |
239 T (char, 1, arr + SR ( -1, 0), s, n); | |
240 T (char, 1, arr + SR ( -1, 1), s, n); | |
241 T (char, 1, arr + SR ( -1, DIFF_MAX), s, n); | |
242 T (char, 1, arr + SR ( 0, 1), s, n); | |
243 T (char, 1, arr + SR ( 0, DIFF_MAX), s, n); | |
244 T (char, 1, arr + SR ( 1, 2), s, n); | |
245 T (char, 1, arr + SR ( 1, DIFF_MAX), s, n); | |
246 | |
247 /* Verify that all offsets via a pointer to an uknown object are | |
248 accepted. */ | |
249 | |
250 /* Negative indices between [DIFF_MIN, DIFF_MAX] are valid since | |
251 the pointer to which the offset is applied can be at a positive | |
252 offset from the beginning of an object. */ | |
253 T (char, 1, d + SR (DIFF_MIN, 0), s, n); | |
254 T (char, 1, d + SR (DIFF_MIN, -1), s, n); | |
255 T (char, 1, d + SR (DIFF_MIN, 1), s, n); | |
256 T (char, 1, d + SR (DIFF_MIN, DIFF_MAX), s, n); | |
257 T (char, 1, d + SR ( -2, -1), s, n); | |
258 T (char, 1, d + SR ( -1, 0), s, n); | |
259 T (char, 1, d + SR ( -1, 1), s, n); | |
260 T (char, 1, d + SR ( -1, DIFF_MAX), s, n); | |
261 T (char, 1, d + SR ( 0, 1), s, n); | |
262 T (char, 1, d + SR ( 0, DIFF_MAX), s, n); | |
263 T (char, 1, d + SR ( 1, 2), s, n); | |
264 T (char, 1, d + SR ( 1, DIFF_MAX), s, n); | |
265 } | |
266 | |
267 #define TI(type, N, init, dst, src) do { \ | |
268 type UNIQUE_NAME (a)[N] = init; \ | |
269 type *a = UNIQUE_NAME (a); \ | |
270 type *pd = (dst); \ | |
271 const type *ps = (src); \ | |
272 FUNC (pd, ps); \ | |
273 sink (a, pd, ps, s); \ | |
274 } while (0) | |
275 | |
276 void test_strcpy_bounds (char *d, const char *s) | |
277 { | |
278 #undef FUNC | |
279 #define FUNC strcpy | |
280 | |
281 ptrdiff_t i; | |
282 | |
283 TI (char, 1, "", a, a + SR (DIFF_MIN, 0)); | |
284 TI (char, 1, "", a, a + SR (-1, 0)); | |
285 TI (char, 1, "", a, a + SR (-1, 1)); | |
286 TI (char, 1, "", a, a + SR (0, 1)); | |
287 TI (char, 1, "", a, a + SR (0, DIFF_MAX - 1)); | |
288 TI (char, 2, "0", a, a + SR (0, DIFF_MAX - 1)); | |
289 TI (char, 2, "0", a, a + SR (1, DIFF_MAX - 1)); | |
290 /* The following needs a warning for reading past the end. */ | |
291 TI (char, 2, "0", a, a + SR (2, DIFF_MAX - 1)); | |
292 TI (char, 2, "0", a, a + SR (3, DIFF_MAX - 1)); /* { dg-warning "offset \\\[3, \[0-9\]+] is out of the bounds \\\[0, 2] of object \[^\n\r\]+ with type .char ?\\\[2\\\]." "strcpy" } */ | |
293 | |
294 TI (char, 3, "01", a, a + SR (0, DIFF_MAX - 1)); | |
295 TI (char, 3, "01", a, a + SR (1, DIFF_MAX - 1)); | |
296 TI (char, 3, "01", a, a + SR (2, DIFF_MAX - 1)); | |
297 /* The following needs a warning for reading past the end. */ | |
298 TI (char, 3, "01", a, a + SR (3, DIFF_MAX - 1)); | |
299 TI (char, 3, "01", a, a + SR (4, DIFF_MAX - 1)); /* { dg-warning "offset \\\[4, \[0-9\]+] is out of the bounds \\\[0, 3] of object \[^\n\r\]+ with type .char ?\\\[3\\\]." "strcpy" } */ | |
300 | |
301 TI (char, 4, "012", a, a + SR (DIFF_MAX - 2, DIFF_MAX - 1)); /* { dg-warning "offset \\\[\[0-9\]+, \[0-9\]+] is out of the bounds \\\[0, 4] of object \[^\n\r\]+ with type .char ?\\\[4\\\]." "strcpy" } */ | |
302 | |
303 | |
304 TI (char, 1, "", a + SR (DIFF_MIN, 0), s); | |
305 TI (char, 1, "", a + SR (-1, 0), s); | |
306 TI (char, 1, "", a + SR (-1, 1), s); | |
307 TI (char, 1, "", a + SR (0, 1), s); | |
308 TI (char, 1, "", a + SR (0, DIFF_MAX - 1), s); | |
309 TI (char, 2, "", a + SR (0, DIFF_MAX - 1), s); | |
310 TI (char, 2, "", a + SR (1, DIFF_MAX - 1), s); | |
311 /* The following is diagnosed not because the initial source offset | |
312 it out of bounds (it isn't) but because the final source offset | |
313 after the access has completed, is. It would be clearer if | |
314 the warning mentioned the final offset. */ | |
315 TI (char, 2, "", a + SR (2, DIFF_MAX - 1), s); /* { dg-warning "forming offset 3 is out of the bounds \\\[0, 2] of object \[^\n\r\]+ with type .char ?\\\[2\\\]." "strcpy" } */ | |
316 TI (char, 2, "", a + SR (3, DIFF_MAX - 1), s); /* { dg-warning "offset \\\[3, \[0-9\]+] is out of the bounds \\\[0, 2] of object \[^\n\r\]+ with type .char ?\\\[2\\\]." "strcpy" } */ | |
317 | |
318 TI (char, 3, "", a + SR (0, DIFF_MAX - 1), s); | |
319 TI (char, 3, "", a + SR (1, DIFF_MAX - 1), s); | |
320 TI (char, 3, "", a + SR (2, DIFF_MAX - 1), s); | |
321 TI (char, 3, "", a + SR (3, DIFF_MAX - 1), s); /* { dg-warning "forming offset 4 is out of the bounds \\\[0, 3] of object \[^\n\r\]+ with type .char ?\\\[3\\\]." "strcpy" } */ | |
322 TI (char, 3, "", a + SR (4, DIFF_MAX - 1), s); /* { dg-warning "offset \\\[4, \[0-9\]+] is out of the bounds \\\[0, 3] of object \[^\n\r\]+ with type .char ?\\\[3\\\]." "strcpy" } */ | |
323 | |
324 TI (char, 4, "", a + SR (DIFF_MAX - 2, DIFF_MAX - 1), s); /* { dg-warning "offset \\\[\[0-9\]+, \[0-9\]+] is out of the bounds \\\[0, 4] of object \[^\n\r\]+ with type .char ?\\\[4\\\]." "strcpy" } */ | |
325 } | |
326 | |
327 struct MA | |
328 { | |
329 int i; | |
330 char a5[5]; | |
331 char a11[11]; | |
332 }; | |
333 | |
334 struct MA2 | |
335 { | |
336 struct MA ma3[3]; | |
337 struct MA ma5[5]; | |
338 char ax[]; | |
339 }; | |
340 | |
341 struct MA3 | |
342 { | |
343 struct MA2 ma5[3]; | |
344 struct MA2 ma7[7]; | |
345 }; | |
346 | |
347 void test_strcpy_bounds_memarray_range (void) | |
348 { | |
349 #undef TM | |
350 #define TM(mem, init, dst, src) \ | |
351 do { \ | |
352 struct MA ma; \ | |
353 strcpy (ma.mem, init); \ | |
354 strcpy (dst, src); \ | |
355 sink (&ma); \ | |
356 } while (0) | |
357 | |
358 ptrdiff_t i = SR (1, 2); | |
359 | |
360 TM (a5, "0", ma.a5 + i, ma.a5); | |
361 TM (a5, "01", ma.a5 + i, ma.a5); | |
362 TM (a5, "012", ma.a5 + i, ma.a5); | |
363 TM (a5, "0123", ma.a5 + i, ma.a5); /* { dg-warning "offset 10 from the object at .ma. is out of the bounds of referenced subobject .\(MA::\)?a5. with type .char ?\\\[5]. at offset 4" "strcpy" } */ | |
364 | |
365 TM (a11, "0", ma.a5, ma.a11); | |
366 TM (a11, "01", ma.a5, ma.a11); | |
367 TM (a11, "012", ma.a5, ma.a11); | |
368 TM (a11, "0123", ma.a5, ma.a11); | |
369 TM (a11, "01234", ma.a5, ma.a11); /* { dg-warning "offset 10 from the object at .ma. is out of the bounds of referenced subobject .\(MA::\)?a5. with type .char ?\\\[5]' at offset 4" } */ | |
370 TM (a11, "012345", ma.a5, ma.a11); /* { dg-warning "offset \\\[10, 11] from the object at .ma. is out of the bounds of referenced subobject .\(MA::\)?a5. with type .char ?\\\[5]' at offset 4" } */ | |
371 TM (a11, "0123456", ma.a5, ma.a11); /* { dg-warning "offset \\\[10, 12] from the object at .ma. is out of the bounds of referenced subobject .\(MA::\)?a5. with type .char ?\\\[5]' at offset 4" } */ | |
372 | |
373 TM (a11, "0123456", ma.a11 + i, "789abcd"); | |
374 } | |
375 | |
376 void test_strcpy_bounds_memarray_var (struct MA *pma, | |
377 struct MA2 *pma2, | |
378 struct MA3 *pma3, | |
379 const char *s, size_t n) | |
380 { | |
381 #undef TM | |
382 #define TM(dst, src) do { \ | |
383 strcpy (dst, src); \ | |
384 sink (dst, src); \ | |
385 } while (0) | |
386 | |
387 TM (pma->a5, s); | |
388 TM (pma->a5 + 0, s); | |
389 TM (pma->a5 + 1, s); | |
390 TM (pma->a5 + 4, s); | |
391 | |
392 /* The following forms a pointer during the call that's outside | |
393 the bounds of the array it was derived from (pma->a5) so | |
394 it should be diagnosed but the representation of the pointer | |
395 addition doesn't contain information to distinguish it from | |
396 the valid pma->a11 + 1 so this is an XFAIL. */ | |
397 TM (pma->a5 + 5, s); /* { dg-warning "offset 17 from the object at .pma. is out of the bounds of .struct MA." "strcpy" { xfail *-*-* } } */ | |
398 | |
399 /* The following also forms an out-of-bounds pointer but similar | |
400 to the above, there is no reliable way to distinguish it from | |
401 (char*)&pma[1].i + 1 so this too is not diagnosed. */ | |
402 TM (pma->a5 + sizeof *pma + 1, s); /* { dg-warning "offset 17 from the object at .pma. is out of the bounds of .struct MA." "strcpy" { xfail *-*-* } } */ | |
403 | |
404 TM (pma->a5 - 1, s); /* { dg-warning "offset -1 from the object at .pma. is out of the bounds of .struct MA." "strcpy" { xfail *-*-* } } */ | |
405 | |
406 TM (pma[1].a5, s); | |
407 TM (pma[2].a5 + 0, s); | |
408 TM (pma[3].a5 + 1, s); | |
409 TM (pma[4].a5 + 4, s); | |
410 | |
411 | |
412 extern struct MA3 ma3[3]; | |
413 TM (ma3[0].ma5[0].ma3[0].a5 + 6, s); | |
414 } |