1 /* PR tree-optimization/89350 - Wrong -Wstringop-overflow warning
2 on a variable offset from the end of an array
3 Test exercising -Wstringop-truncation with -Wall.
4 -Wstringop-truncation is disabled to avoid warnings for strncpy
5 calls whose bound matches the size of the destination getting
6 in the way of -Wstringop-overflow.
7 { dg-do compile }
8 { dg-options "-O2 -Wall -Wno-stringop-truncation -ftrack-macro-expansion=0" } */
9
10 #include "range.h"
11
12 extern void* memcpy (void*, const void*, size_t);
13 extern void* memset (void*, int, size_t);
14 extern char* strcpy (char*, const char*);
15 extern char* strncpy (char*, const char*, size_t);
16
17 void sink (void*);
18
19 #define CAT(pfx, line) pfx ## line
20 #define CONCAT(pfx, line) CAT (pfx, line)
21 #define UNIQ_NAME(pfx) CONCAT (pfx, __LINE__)
22
23 /* Exercise a call to memset with a distinct destination object each
24 time to prevent GCC from reusing the destination pointer in later
25 tests. */
26 #define T(off1, off2, n) \
27 do { \
28 extern char UNIQ_NAME (ga)[7]; \
29 char *d = UNIQ_NAME (ga) + off1; \
30 d += off2; \
31 memset (d, 0, n); \
32 sink (d); \
33 } while (0)
34
35
36 /* Exercise calls to memset with a destination pointer pointing to
37 an array plus constant offset plus variable offset, in that order. */
38
39 void test_memset_array_cst_range_off (void)
40 {
41 T (1, SR (-7, 7), 7);
42 T (1, SR (-1, 1), 7);
43 T (1, SR (-1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
44 T (1, SR ( 1, 2), 1);
45 T (1, SR ( 1, 2), 5);
46
47 T (1, SR ( 0, 1), 6);
48 T (1, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
49
50 T (2, SR (-7, 7), 7);
51 T (2, SR (-2, 7), 7);
52 T (2, SR (-1, 1), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
53 T (2, SR (-1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
54 T (2, SR ( 1, 2), 1);
55 T (2, SR ( 1, 2), 3);
56 T (2, SR ( 1, 2), 4);
57 T (2, SR ( 1, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
58
59 T (2, SR ( 0, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
60 T (2, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
61 T (7, UR (-7, 0), 7);
62 T (7, UR (-7, 0), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
63 T (7, UR (-3, 2), 3);
64 T (7, UR (-2, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
65 }
66
67
68 /* Exercise calls to memset with a destination pointer pointing to
69 an array plus variable offset plus constant offset. */
70
71 void test_memset_array_range_cst_off (void)
72 {
73 T (SR (-7, 7), 1, 7);
74 T (SR (-1, 1), 1, 7);
75 T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
76 T (SR ( 1, 2), 1, 1);
77 T (SR ( 1, 2), 1, 5);
78
79 T (SR ( 0, 1), 1, 6);
80 T (UR ( 1, 2), 1, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
81
82 T (SR (-7, 7), 2, 7);
83 T (SR (-1, 1), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
84 T (SR (-1, 1), 2, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
85 T (SR ( 1, 2), 2, 1);
86 T (SR ( 1, 2), 2, 3);
87 T (SR ( 1, 2), 2, 4);
88 T (SR ( 1, 2), 2, 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
89
90 T (SR ( 0, 1), 2, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
91
92 T (UR ( 1, 2), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
93 }
94
95
96 void test_memset_array_range_range_off (void)
97 {
98 T (UR (0, 1), UR (0, 1), 7);
99 T (UR (3, 5), UR (2, 7), 1);
100 T (UR (3, 7), UR (2, 9), 2);
101 T (UR (3, 9), UR (2, 9), 3); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
102 T (UR (0, 1), UR (1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
103 }
104
105
106 #undef T
107 #define T(off1, off2, n) \
108 do { \
109 extern char UNIQ_NAME (ga)[7]; \
110 char *d = UNIQ_NAME (ga) + off1; \
111 d += off2; \
112 memcpy (d, s, n); \
113 sink (d); \
114 } while (0)
115
116
117 void test_memcpy_array_cst_range_off (const void *s)
118 {
119 T (1, SR (-7, 7), 7);
120 T (1, SR (-1, 1), 7);
121 T (1, SR (-1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
122 T (1, SR ( 1, 2), 1);
123 T (1, SR ( 1, 2), 5);
124
125 T (1, SR ( 0, 1), 6);
126 T (1, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
127
128 T (2, SR (-7, 7), 7);
129 T (2, SR (-2, 7), 7);
130 T (2, SR (-1, 1), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
131 T (2, SR (-1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
132 T (2, SR ( 1, 2), 1);
133 T (2, SR ( 1, 2), 3);
134 T (2, SR ( 1, 2), 4);
135 T (2, SR ( 1, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
136
137 T (2, SR ( 0, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
138 T (2, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
139 T (7, UR (-7, 0), 7);
140 T (7, UR (-7, 0), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
141 T (7, UR (-3, 2), 3);
142 T (7, UR (-2, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
143 }
144
145
146 void test_memcpy_array_range_cst_off (const void *s)
147 {
148 T (SR (-7, 7), 1, 7);
149 T (SR (-1, 1), 1, 7);
150 T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
151 T (SR ( 1, 2), 1, 1);
152 T (SR ( 1, 2), 1, 5);
153
154 T (SR ( 0, 1), 1, 6);
155 T (UR ( 1, 2), 1, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
156
157 T (SR (-7, 7), 2, 7);
158 T (SR (-1, 1), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
159 T (SR (-1, 1), 2, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
160 T (SR ( 1, 2), 2, 1);
161 T (SR ( 1, 2), 2, 3);
162 T (SR ( 1, 2), 2, 4);
163 T (SR ( 1, 2), 2, 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
164
165 T (SR ( 0, 1), 2, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
166
167 T (UR ( 1, 2), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
168 }
169
170
171 void test_memcpy_array_range_range_off (const void *s)
172 {
173 T (UR (0, 1), UR (0, 1), 7);
174 T (UR (3, 5), UR (2, 7), 1);
175 T (UR (3, 7), UR (2, 9), 2);
176 T (UR (3, 9), UR (2, 9), 3); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
177 T (UR (0, 1), UR (1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
178 }
179
180
181 #undef T
182 #define T(off1, off2, n) \
183 do { \
184 extern char UNIQ_NAME (ga)[7]; \
185 char *d = UNIQ_NAME (ga) + off1; \
186 d += off2; \
187 const char str[] = "0123456789"; \
188 const char *s = str + sizeof str - 1 - n; \
189 strcpy (d, s); \
190 sink (d); \
191 } while (0)
192
193
194 void test_strcpy_array_cst_range_off (void)
195 {
196 T (1, SR (-7, 7), 6);
197 T (1, SR (-1, 1), 6);
198 T (1, SR (-1, 1), 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
199 T (1, SR ( 1, 2), 0);
200 T (1, SR ( 1, 2), 4);
201
202 T (1, SR ( 0, 1), 5);
203 T (1, UR ( 1, 2), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
204
205 T (2, SR (-7, 7), 6);
206 T (2, SR (-2, 7), 6);
207 T (2, SR (-1, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
208 T (2, SR (-1, 1), 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
209 T (2, SR ( 1, 2), 0);
210 T (2, SR ( 1, 2), 2);
211 T (2, SR ( 1, 2), 3);
212 T (2, SR ( 1, 2), 4); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
213
214 T (2, SR ( 0, 1), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
215 T (2, UR ( 1, 2), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
216 T (7, UR (-7, 0), 6);
217 T (7, UR (-7, 0), 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
218 T (7, UR (-3, 2), 2);
219 T (7, UR (-2, 2), 4); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
220 }
221
222
223 void test_strcpy_array_range_cst_off (const char *s)
224 {
225 T (SR (-7, 7), 1, 6);
226 T (SR (-1, 1), 1, 6);
227 T (SR (-1, 1), 1, 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
228 T (SR ( 1, 2), 1, 0);
229 T (SR ( 1, 2), 1, 1);
230 T (SR ( 1, 2), 1, 4);
231
232 T (SR ( 0, 1), 1, 5);
233 T (UR ( 1, 2), 1, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
234
235 T (SR (-7, 7), 2, 6);
236 T (SR (-1, 1), 2, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
237 T (SR (-1, 1), 2, 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
238 T (SR ( 1, 2), 2, 0);
239 T (SR ( 1, 2), 2, 1);
240 T (SR ( 1, 2), 2, 2);
241 T (SR ( 1, 2), 2, 3);
242 T (SR ( 1, 2), 2, 4); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
243
244 T (SR ( 0, 1), 2, 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
245
246 T (UR ( 1, 2), 2, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
247 }
248
249
250 #undef T
251 #define T(off1, off2, n) \
252 do { \
253 extern char UNIQ_NAME (ga)[7]; \
254 char *d = UNIQ_NAME (ga) + off1; \
255 d += off2; \
256 strncpy (d, s, n); \
257 sink (d); \
258 } while (0)
259
260
261 void test_strncpy_array_cst_range_off (const char *s)
262 {
263 T (1, SR (-7, 7), 7);
264 T (1, SR (-1, 1), 7);
265 T (1, SR (-1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
266 T (1, SR ( 1, 2), 1);
267 T (1, SR ( 1, 2), 5);
268
269 T (1, SR ( 0, 1), 6);
270 T (1, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
271
272 T (2, SR ( -7, 7), 7);
273 T (2, SR ( -1, 1), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
274 T (2, SR ( -1, 1), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
275 T (2, SR ( 1, 2), 1);
276 T (2, SR ( 1, 2), 3);
277 T (2, SR ( 1, 2), 4);
278 T (2, SR ( 1, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
279
280 T (2, SR ( 0, 1), 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
281 T (2, UR ( 1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
282 T (7, UR (-7, 0), 7);
283 T (7, UR (-7, 0), 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
284 T (7, UR (-3, 2), 3);
285 T (7, UR (-2, 2), 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
286 }
287
288
289 void test_strncpy_array_range_cst_off (const char *s)
290 {
291 T (SR (-7, 7), 1, 7);
292 T (SR (-1, 1), 1, 7);
293 T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
294 T (SR ( 1, 2), 1, 1);
295 T (SR ( 1, 2), 1, 5);
296
297 T (SR ( 0, 1), 1, 6);
298 T (UR ( 1, 2), 1, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
299
300 T (SR (-7, 7), 2, 7);
301 T (SR (-1, 1), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
302 T (SR (-1, 1), 2, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
303 T (SR ( 1, 2), 2, 1);
304 T (SR ( 1, 2), 2, 3);
305 T (SR ( 1, 2), 2, 4);
306 T (SR ( 1, 2), 2, 5); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
307
308 T (SR ( 0, 1), 2, 6); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
309
310 T (UR ( 1, 2), 2, 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
311 }
312
313
314 void test_strncpy_array_range_range_off (const char *s)
315 {
316 T (UR (0, 1), UR (0, 1), 7);
317 T (UR (3, 5), UR (2, 7), 1);
318 T (UR (3, 7), UR (2, 9), 2);
319 T (UR (3, 9), UR (2, 9), 3); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
320 T (UR (0, 1), UR (1, 2), 7); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
321 }