1 /* Test for MIN and MAX expressions involving pointers.
3 { dg-options "-O2 -Wall -Wno-array-bounds -ftrack-macro-expansion=0" } */
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
;
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. */
35 char *q
= MIN (p1
, p2
);
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
53 char *q
= MIN (p1
, p2
);
57 memset (q
, 0, INT_MAX
);
61 /* Exercise both pointers pointing to the same object plus constant
63 char a2
[2]; // { dg-message "at offset 1 into destination object 'a2' of size 2" "note" }
67 char *q
= MIN (p1
, p2
);
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
76 char a3
[3]; // { dg-message "at offset \\\[1, 3] into destination object 'a3'" "note" }
80 char *q
= MIN (pi
, pj
);
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" }
95 char *q
= MIN (pi
, pj
);
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" }
109 char *q
= MIN (p
, a5
);
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" }
123 char *q
= MIN (p1
, p2
);
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" }
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
);
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
152 char a8
[8]; // { dg-message "at offset 1 into destination object 'a8'" "note" }
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
158 char *q
= MIN (p1
, p2
);
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" }
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
);
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" }
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
);
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" }
202 char *q
= MIN (p1
, p2
);
207 memset (q
, 0, 4); // { dg-warning "writing 4 bytes into a region of size 3 " }
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
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
233 char a3
[3]; // { dg-message "at offset \\\[1, 3] into destination object 'a3'" "note" }
237 char *q
= MAX (pi
, pj
);
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" }
252 char *q
= MAX (pi
, pj
);
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" }
266 char *q
= MAX (p
, a5
);
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" }
280 char *q
= MAX (p1
, p2
);
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" }
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
);
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
308 char a8
[8]; // { dg-message "at offset 2 into destination object 'a8'" "note" }
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
314 char *q
= MAX (p1
, p2
);
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" }
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
);
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" }
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" }
355 char *q
= MAX (p1
, p2
);
360 memset (q
, 0, 11); // { dg-warning "writing 11 bytes into a region of size 10 " }