libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / testsuite / gcc.dg / Wstringop-overflow-62.c
blobd589f077887e150f944ccbc04863f3c77a57db0a
1 /* Test for MIN and MAX expressions involving pointers.
2 { dg-do compile }
3 { dg-options "-O2 -Wall -Wno-array-bounds -ftrack-macro-expansion=0" } */
5 #include "range.h"
7 #define INT_MAX __INT_MAX__
9 #define MIN(x, y) ((x) < (y) ? (x) : (y))
10 #define MAX(x, y) ((x) < (y) ? (y) : (x))
12 typedef __SIZE_TYPE__ size_t;
14 void* memset (void*, int, size_t);
15 #define memset(...) sink (memset (__VA_ARGS__))
17 void sink (void*, ...);
19 volatile int cond, vi;
20 char* volatile ptr;
22 void test_min (void)
24 const int i1 = SR (1, INT_MAX);
25 const int i2 = SR (2, INT_MAX);
28 /* Exercise both pointers pointing to a different unknown object plus
29 positive constant offset. Since PTR is volatile P1 and P2 cannot
30 normally be considered to point to the same object. It can only
31 be inferred from the MIN expression. */
32 char *p1 = ptr + 1;
33 char *p2 = ptr + 2;
35 char *q = MIN (p1, p2);
37 memset (q, 0, 1);
38 memset (q, 0, 2);
39 memset (q, 0, INT_MAX);
40 // { dg-warning "writing 2147483647 bytes into a region of size 2147483646" "ilp32" { target ilp32 } .-1 }
41 memset (q, 0, DIFF_MAX - 2);
42 memset (q, 0, DIFF_MAX);
43 // { dg-warning "writing 2147483647 bytes into a region of size 2147483646" "ilp32" { target ilp32 } .-1 }
44 // { dg-warning "writing 9223372036854775807 bytes into a region of size 9223372036854775806" "not-ilp32" { target { ! ilp32 } } .-2 }
48 /* Exercise both pointers pointing to a different unknown object plus
49 variable offset. */
50 char *p1 = ptr + vi;
51 char *p2 = ptr + vi;
53 char *q = MIN (p1, p2);
55 memset (q, 0, 1);
56 memset (q, 0, 2);
57 memset (q, 0, INT_MAX);
61 /* Exercise both pointers pointing to the same object plus constant
62 offset. */
63 char a2[2]; // { dg-message "at offset 1 into destination object 'a2' of size 2" "note" }
64 char *p1 = a2 + 1;
65 char *p2 = a2 + 2;
67 char *q = MIN (p1, p2);
69 memset (q, 0, 1);
70 memset (q, 0, 2); // { dg-warning "writing 2 bytes into a region of size 1 " }
74 /* Exercise both pointers pointing to the same object plus offset
75 in a known range. */
76 char a3[3]; // { dg-message "at offset \\\[1, 3] into destination object 'a3'" "note" }
77 char *pi = a3 + i1;
78 char *pj = a3 + i2;
80 char *q = MIN (pi, pj);
82 memset (q, 0, 1);
83 memset (q, 0, 2);
84 memset (q, 0, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
88 /* Exercise both pointers pointing to the same object plus variable
89 offset. Verify that no offset is mentioned in the note (since
90 its unknown, printing its full range is unnecessary). */
91 char a4[4]; // { dg-message ": destination object 'a4'" "note" }
92 char *pi = a4 + vi;
93 char *pj = a4 + vi;
95 char *q = MIN (pi, pj);
97 memset (q, 0, 1);
98 memset (q, 0, 2);
99 memset (q, 0, 3);
100 memset (q, 0, 4);
101 memset (q, 0, 5); // { dg-warning "writing 5 bytes into a region of size 4 " }
105 /* Exercise a pointer pointing to a known object with one pointing
106 to an unknown object. */
107 char a5[5]; // { dg-message ": destination object 'a5'" "note" }
108 char *p = ptr;
109 char *q = MIN (p, a5);
111 memset (q, 0, 1);
112 memset (q, 0, 2);
113 memset (q, 0, 5);
114 memset (q, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5 " }
118 /* Exercise a pointer pointing to a known object plus constant offset
119 with one pointing to an unknown object. */
120 char a6[6]; // { dg-message "(at offset 1 into )?destination object 'a6'" "note" }
121 char *p1 = ptr;
122 char *p2 = a6 + 1;
123 char *q = MIN (p1, p2);
125 memset (q, 0, 1);
126 memset (q, 0, 2);
127 memset (q, 0, 6);
128 memset (q, 0, 7); // { dg-warning "writing 7 bytes into a region of size 6 " }
132 /* Exercise a pointer pointing to a known object with one pointing
133 to an unknown object plus constant offset. */
134 char a7[7]; // { dg-message ": destination object 'a7'" "note" }
135 char *p1 = a7;
136 char *p2 = ptr + 1;
137 /* Since p1 points to a7[0] it must be less than any pointer to a7
138 plus positive offset, and so Q == P1. */
139 char *q = MIN (p1, p2);
141 memset (q, 0, 1);
142 memset (q, 0, 2);
143 memset (q, 0, 3);
144 memset (q, 0, 7);
145 memset (q, 0, 8); // { dg-warning "writing 8 bytes into a region of size 7 " }
149 /* Exercise a pointer pointing to a known object plus constant offset
150 with one pointing to an unknown object plus a different constant
151 offset. */
152 char a8[8]; // { dg-message "at offset 1 into destination object 'a8'" "note" }
153 char *p1 = a8 + 1;
154 char *p2 = ptr + 2;
155 /* Since P1 points to A8[1] it must be less than or equal to any
156 pointer to A8 plus positive offset. Either way, Q must point
157 to A8[1]. */
158 char *q = MIN (p1, p2);
160 memset (q, 0, 1);
161 memset (q, 0, 2);
162 memset (q, 0, 7);
163 memset (q, 0, 8); // { dg-warning "writing 8 bytes into a region of size 7 " }
167 /* Same as above but with larger offsets. */
168 char a9[9]; // { dg-message "at offset 3 into destination object 'a9'" "note" }
169 char *p1 = a9 + 3;
170 char *p2 = ptr + 4;
171 /* Since P1 points to A9[3] it must be less than or equal to any
172 pointer anywhere into A9 plus 4, so Q must point to A9[3]. */
173 char *q = MIN (p1, p2);
175 memset (q, 0, 1);
176 memset (q, 0, 2);
177 memset (q, 0, 6);
178 memset (q, 0, 7); // { dg-warning "writing 7 bytes into a region of size 6 " }
182 /* Same as above but with the offsets reversed. */
183 char a10[10]; // { dg-message "at offset 5 into destination object 'a10'" "note" }
184 char *p1 = a10 + 10;
185 char *p2 = ptr + 5;
186 /* Since P1 points just past the end of A10 it could be either less
187 or equal to another pointer anywhere into A10 plus 3 because
188 the other pointer itself could start at a non-zero offset that's
189 not reflected in the determined offset). */
190 char *q = MIN (p1, p2);
192 memset (q, 0, 1);
193 memset (q, 0, 2);
194 memset (q, 0, 5);
195 memset (q, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5 " }
199 char a3[3]; // { dg-message ": destination object 'a3'" "note" }
200 char *p1 = ptr;
201 char *p2 = a3 + i1;
202 char *q = MIN (p1, p2);
204 memset (q, 0, 1);
205 memset (q, 0, 2);
206 memset (q, 0, 3);
207 memset (q, 0, 4); // { dg-warning "writing 4 bytes into a region of size 3 " }
212 void test_max (void)
214 const int i1 = SR (1, INT_MAX);
215 const int i2 = SR (2, INT_MAX);
218 /* Exercise both pointers pointing to the same object plus constant
219 offset. */
220 char a2[2];
221 char *pi = a2 + 1;
222 char *pj = a2 + 2;
224 char *q = MAX (pi, pj);
226 memset (q, 0, 1); // { dg-warning "writing 1 byte into a region of size 0 " }
227 memset (q, 0, 2); // { dg-warning "writing 2 bytes into a region of size 0 " }
231 /* Exercise both pointers pointing to the same object plus offset
232 in a known range. */
233 char a3[3]; // { dg-message "at offset \\\[1, 3] into destination object 'a3'" "note" }
234 char *pi = a3 + i1;
235 char *pj = a3 + i2;
237 char *q = MAX (pi, pj);
239 memset (q, 0, 1);
240 memset (q, 0, 2);
241 memset (q, 0, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
245 /* Exercise both pointers pointing to the same object plus variable
246 offset. Verify that no offset is mentioned in the note (since
247 its unknown, printing its full range is unnecessary). */
248 char a4[4]; // { dg-message ": destination object 'a4'" "note" }
249 char *pi = a4 + vi;
250 char *pj = a4 + vi;
252 char *q = MAX (pi, pj);
254 memset (q, 0, 1);
255 memset (q, 0, 2);
256 memset (q, 0, 3);
257 memset (q, 0, 4);
258 memset (q, 0, 5); // { dg-warning "writing 5 bytes into a region of size 4 " }
262 /* Exercise a pointer pointing to a known object with one pointing
263 to an unknown object. */
264 char a5[5]; // { dg-message ": destination object 'a5'" "note" }
265 char *p = ptr;
266 char *q = MAX (p, a5);
268 memset (q, 0, 1);
269 memset (q, 0, 2);
270 memset (q, 0, 5);
271 memset (q, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5 " }
275 /* Exercise a pointer pointing to a known object plus constant offset
276 with one pointing to an unknown object. */
277 char a6[6]; // { dg-message "at offset 1 into destination object 'a6'" "note" }
278 char *p1 = ptr;
279 char *p2 = a6 + 1;
280 char *q = MAX (p1, p2);
282 memset (q, 0, 1);
283 memset (q, 0, 5);
284 memset (q, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5 " }
285 memset (q, 0, 7); // { dg-warning "writing 7 bytes into a region of size 5 " }
289 /* Exercise a pointer pointing to a known object with one pointing
290 to an unknown object plus constant offset. */
291 char a7[7]; // { dg-message "at offset 1 into destination object 'a7'" "note" }
292 char *p1 = a7;
293 char *p2 = ptr + 1;
294 /* Since p1 points to a7[0] it must be less than any pointer to a7
295 plus positive offset, and so Q == P2. */
296 char *q = MAX (p1, p2);
298 memset (q, 0, 1);
299 memset (q, 0, 6);
300 memset (q, 0, 7); // { dg-warning "writing 7 bytes into a region of size 6 " }
301 memset (q, 0, 8); // { dg-warning "writing 8 bytes into a region of size 6 " }
305 /* Exercise a pointer pointing to a known object plus constant offset
306 with one pointing to an unknown object plus a different constant
307 offset. */
308 char a8[8]; // { dg-message "at offset 2 into destination object 'a8'" "note" }
309 char *p1 = a8 + 1;
310 char *p2 = ptr + 2;
311 /* Since P1 points to A8[1] it must be less than or equal to any
312 pointer to A8 plus positive offset. Either way, Q must point
313 to A8[2]. */
314 char *q = MAX (p1, p2);
316 memset (q, 0, 1);
317 memset (q, 0, 6);
318 memset (q, 0, 7); // { dg-warning "writing 7 bytes into a region of size 6 " }
319 memset (q, 0, 8); // { dg-warning "writing 8 bytes into a region of size 6 " }
323 /* Same as above but with larger offsets. */
324 char a9[9]; // { dg-message "at offset 4 into destination object 'a9'" "note" }
325 char *p1 = a9 + 3;
326 char *p2 = ptr + 4;
327 /* Since P1 points to A9[3] it must be less than or equal to any
328 pointer anywhere into A9 plus 4, so Q must point to A9[4]. */
329 char *q = MAX (p1, p2);
331 memset (q, 0, 1);
332 memset (q, 0, 2);
333 memset (q, 0, 5);
334 memset (q, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5 " }
338 /* Same as above but with the offsets reversed. */
339 char a10[10]; // { dg-message "at offset 10 into destination object 'a10'" "note" }
340 char *p1 = a10 + 10;
341 char *p2 = ptr + 5;
342 /* Since P1 points just past the end of A10 it could be either less
343 or equal to another pointer anywhere into A10 plus 3 because
344 the other pointer itself could start at a non-zero offset that's
345 not reflected in the determaxed offset). */
346 char *q = MAX (p1, p2);
348 memset (q, 0, 1); // { dg-warning "writing 1 byte into a region of size 0 " }
352 char a11[11]; // { dg-message "at offset \\\[1, 11] into destination object 'a11'" "note" }
353 char *p1 = ptr;
354 char *p2 = a11 + i1;
355 char *q = MAX (p1, p2);
357 memset (q, 0, 1);
358 memset (q, 0, 2);
359 memset (q, 0, 10);
360 memset (q, 0, 11); // { dg-warning "writing 11 bytes into a region of size 10 " }