1 /* PR c/77531 - __attribute__((alloc_size(1,2))) could also warn on
2 multiplication overflow
3 PR c/78284 - warn on malloc with very large arguments
4 Test exercising the ability to detect and diagnose calls to allocation
5 functions decorated with attribute alloc_size that either overflow or
6 exceed the default maximum object size (with -Walloc-size-larger-than
7 not explicitly specified). */
8 /* { dg-do compile { target size32plus } } */
9 /* { dg-options "-O2 -Wall" } */
11 #define SCHAR_MAX __SCHAR_MAX__
12 #define SCHAR_MIN (-SCHAR_MAX - 1)
13 #define UCHAR_MAX (SCHAR_MAX * 2 + 1)
15 #define SHRT_MAX __SHRT_MAX__
16 #define SHRT_MIN (-SHRT_MAX - 1)
17 #define USHRT_MAX (SHRT_MAX * 2 + 1)
19 #define INT_MAX __INT_MAX__
20 #define INT_MIN (-INT_MAX - 1)
21 #define UINT_MAX (INT_MAX * 2U + 1)
23 #define LONG_MAX __LONG_MAX__
24 #define LONG_MIN (-LONG_MAX - 1L)
25 #define ULONG_MAX (LONG_MAX * 2LU + 1)
27 #define LLONG_MAX __LLONG_MAX__
28 #define LLONG_MIN (-LLONG_MAX - 1LL)
29 #define ULLONG_MAX (ULLONG_MAX * 2LLU + 1)
31 #define PTRDIFF_MAX __PTRDIFF_MAX__
32 #define PTRDIFF_MIN (-PTRDIFF_MAX - 1)
33 #define SIZE_MAX __SIZE_MAX__
35 typedef __PTRDIFF_TYPE__
ptrdiff_t;
36 typedef __SIZE_TYPE__
size_t;
38 #define ALLOC_SIZE(...) __attribute__ ((alloc_size (__VA_ARGS__)))
40 void* f_uchar_1 (unsigned char) ALLOC_SIZE (1);
41 void* f_uchar_2 (unsigned char, unsigned char) ALLOC_SIZE (1, 2);
42 void* f_schar_1 (signed char) ALLOC_SIZE (1);
43 void* f_schar_2 (signed char, signed char) ALLOC_SIZE (1, 2);
45 void* f_ushrt_1 (unsigned short) ALLOC_SIZE (1);
46 void* f_ushrt_2 (unsigned short, unsigned short) ALLOC_SIZE (1, 2);
47 void* f_shrt_1 (signed short) ALLOC_SIZE (1);
48 void* f_shrt_2 (signed short, signed short) ALLOC_SIZE (1, 2);
50 void* f_uint_1 (unsigned) ALLOC_SIZE (1);
51 void* f_uint_2 (unsigned, unsigned) ALLOC_SIZE (1, 2);
52 void* f_int_1 (int) ALLOC_SIZE (1);
53 void* f_int_2 (int, int) ALLOC_SIZE (1, 2);
55 void* f_ulong_1 (unsigned long) ALLOC_SIZE (1);
56 void* f_ulong_2 (unsigned long, unsigned long) ALLOC_SIZE (1, 2);
57 void* f_long_1 (long) ALLOC_SIZE (1);
58 void* f_long_2 (long, long) ALLOC_SIZE (1, 2);
60 void* f_ullong_1 (unsigned long long) ALLOC_SIZE (1);
61 void* f_ullong_2 (unsigned long long, unsigned long long) ALLOC_SIZE (1, 2);
62 void* f_llong_1 (long long) ALLOC_SIZE (1);
63 void* f_llong_2 (long long, long long) ALLOC_SIZE (1, 2);
65 void* f_size_1 (size_t) ALLOC_SIZE (1);
66 void* f_size_2 (size_t, size_t) ALLOC_SIZE (1, 2);
69 unsigned_range (size_t min
, size_t max
)
71 extern size_t random_unsigned_value (void);
72 size_t val
= random_unsigned_value ();
73 if (val
< min
|| max
< val
) val
= min
;
78 signed_range (long long min
, long long max
)
80 extern long long random_signed_value (void);
81 long long val
= random_signed_value ();
82 if (val
< min
|| max
< val
) val
= min
;
87 unsigned_anti_range (size_t min
, size_t max
)
89 extern size_t random_unsigned_value (void);
90 size_t val
= random_unsigned_value ();
91 if (min
<= val
&& val
<= max
)
96 #define UR(min, max) unsigned_range (min, max)
97 #define SR(min, max) signed_range (min, max)
99 #define UAR(min, max) unsigned_anti_range (min, max)
100 #define SAR(min, max) signed_anti_range (min, max)
106 test_uchar_cst (void)
108 const unsigned char max
= UCHAR_MAX
;
110 sink (f_uchar_1 (0));
111 sink (f_uchar_1 (1));
112 sink (f_uchar_1 (max
));
114 sink (f_uchar_2 (0, 0));
115 sink (f_uchar_2 (0, 1));
116 sink (f_uchar_2 (1, 0));
117 sink (f_uchar_2 (1, 1));
118 sink (f_uchar_2 (0, max
));
119 sink (f_uchar_2 (max
, 0));
120 sink (f_uchar_2 (max
, max
));
124 test_uchar_range (unsigned char n
, int i
)
126 const unsigned char max
= UCHAR_MAX
;
128 sink (f_uchar_1 (n
));
130 sink (f_uchar_1 (UR (0, 1)));
131 sink (f_uchar_1 (UR (1, max
)));
132 sink (f_uchar_1 (UR (0, max
- 1)));
134 sink (f_uchar_1 (UAR (1, 1)));
135 sink (f_uchar_1 (UAR (1, max
- 1)));
136 sink (f_uchar_1 (UAR (max
- 2, max
- 1)));
138 sink (f_uchar_2 (0, n
));
139 sink (f_uchar_2 (0, i
));
140 sink (f_uchar_2 (n
, 0));
141 sink (f_uchar_2 (i
, 0));
142 sink (f_uchar_2 (1, n
));
143 sink (f_uchar_2 (1, i
));
144 sink (f_uchar_2 (n
, 1));
145 sink (f_uchar_2 (i
, 1));
146 sink (f_uchar_2 (max
, n
));
147 sink (f_uchar_2 (max
, i
));
148 sink (f_uchar_2 (n
, max
));
149 sink (f_uchar_2 (i
, max
));
150 sink (f_uchar_2 (n
, n
));
151 sink (f_uchar_2 (i
, i
));
153 sink (f_uchar_2 (UR (0, 1), UR (0, 1)));
154 sink (f_uchar_2 (UR (1, 2), UR (1, 2)));
155 sink (f_uchar_2 (UR (1, max
), UR (0, 1)));
156 sink (f_uchar_2 (UR (0, 1), UR (1, max
)));
160 test_schar_cst (void)
162 const signed char min
= SCHAR_MIN
;
163 const signed char max
= SCHAR_MAX
;
165 sink (f_schar_1 (min
)); /* { dg-warning "argument 1 value .-\[0-9\]+. is negative" } */
166 sink (f_schar_1 (-1)); /* { dg-warning "argument 1 value .-1. is negative" } */
167 sink (f_schar_1 (0));
168 sink (f_schar_1 (1));
169 sink (f_schar_1 (max
));
171 sink (f_schar_2 (0, min
)); /* { dg-warning "argument 2 value .-\[0-9\]+. is negative" } */
172 sink (f_schar_2 (min
, 0)); /* { dg-warning "argument 1 value .-\[0-9\]+. is negative" } */
173 sink (f_schar_2 (0, -1)); /* { dg-warning "argument 2 value .-1. is negative" } */
174 sink (f_schar_2 (-1, 0)); /* { dg-warning "argument 1 value .-1. is negative" } */
179 test_schar_range (signed char n
)
181 const signed char min
= SCHAR_MIN
;
182 const signed char max
= SCHAR_MAX
;
184 sink (f_schar_1 (n
));
186 sink (f_schar_1 (SR (min
, min
+ 1))); /* { dg-warning "argument 1 range \\\[-\[0-9\]+, -\[0-9\]+\\\] is negative" } */
187 sink (f_schar_1 (SR (min
, 0))); /* { dg-warning "argument 1 range \\\[-\[0-9\]+, 0\\\] is negative" } */
188 sink (f_schar_1 (SR (-1, 0))); /* { dg-warning "argument 1 range \\\[-1, 0\\\] is negative" } */
189 sink (f_schar_1 (SR (-1, 1)));
190 sink (f_schar_1 (SR (0, 1)));
191 sink (f_schar_1 (SR (0, max
- 1)));
192 sink (f_schar_1 (SR (1, max
)));
193 sink (f_schar_1 (SR (max
- 1, max
)));
195 sink (f_schar_2 (n
, n
));
197 sink (f_schar_2 (SR (min
, min
+ 1), n
)); /* { dg-warning "argument 1 range \\\[-\[0-9\]+, -\[0-9\]+\\\] is negative" } */
198 sink (f_schar_2 (n
, SR (min
, min
+ 1))); /* { dg-warning "argument 2 range \\\[-\[0-9\]+, -\[0-9\]+\\\] is negative" } */
199 sink (f_schar_2 (SR (min
, min
+ 1), 0)); /* { dg-warning "argument 1 range \\\[-\[0-9\]+, -\[0-9\]+\\\] is negative" } */
200 sink (f_schar_2 (0, SR (min
, min
+ 1))); /* { dg-warning "argument 2 range \\\[-\[0-9\]+, -\[0-9\]+\\\] is negative" } */
201 sink (f_schar_2 (SR (min
, min
+ 1), min
)); /* { dg-warning "argument 1 range \\\[-\[0-9\]+, -\[0-9\]+\\\] is negative" } */
202 /* { dg-warning "argument 2 value .-\[0-9\]+. is negative" "argument 2" { target *-*-* } .-1 } */
203 sink (f_schar_2 (min
, SR (min
, min
+ 1))); /* { dg-warning "argument 2 range \\\[-\[0-9\]+, -\[0-9\]+\\\] is negative" } */
204 /* { dg-warning "argument 1 value .-\[0-9\]+. is negative" "argument 1" { target *-*-* } .-1 } */
206 sink (f_schar_2 (SR (-1, 0), 0)); /* { dg-warning "argument 1 range \\\[-\[0-9\]+, 0\\\] is negative" } */
207 sink (f_schar_2 (0, SR (-1, 0))); /* { dg-warning "argument 2 range \\\[-\[0-9\]+, 0\\\] is negative" } */
208 sink (f_schar_2 (SR (-1, 0), 1)); /* { dg-warning "argument 1 range \\\[-\[0-9\]+, 0\\\] is negative" } */
209 sink (f_schar_2 (1, SR (-1, 0))); /* { dg-warning "argument 2 range \\\[-\[0-9\]+, 0\\\] is negative" } */
210 sink (f_schar_2 (SR (-1, 0), n
)); /* { dg-warning "argument 1 range \\\[-\[0-9\]+, 0\\\] is negative" } */
211 sink (f_schar_2 (n
, SR (-1, 0))); /* { dg-warning "argument 2 range \\\[-\[0-9\]+, 0\\\] is negative" } */
213 sink (f_schar_2 (max
, SR (1, max
)));
214 sink (f_schar_2 (SR (1, max
), max
));
218 test_ushrt_cst (void)
220 const unsigned short max
= USHRT_MAX
;
222 sink (f_ushrt_1 (0));
223 sink (f_ushrt_1 (1));
224 sink (f_ushrt_1 (max
));
226 sink (f_ushrt_2 (0, 0));
227 sink (f_ushrt_2 (0, 1));
228 sink (f_ushrt_2 (1, 0));
229 sink (f_ushrt_2 (1, 1));
230 sink (f_ushrt_2 (0, max
));
231 sink (f_ushrt_2 (max
, 0));
233 if (max
< SIZE_MAX
&& (size_t)max
* max
< SIZE_MAX
/ 2)
234 sink (f_ushrt_2 (max
, max
));
238 test_ushrt_range (unsigned short n
)
240 const unsigned short max
= USHRT_MAX
;
242 sink (f_ushrt_1 (n
));
243 sink (f_ushrt_1 (UR (0, 1)));
244 sink (f_ushrt_1 (UR (1, max
- 1)));
245 sink (f_ushrt_1 (UR (1, max
)));
246 sink (f_ushrt_1 (UR (0, max
- 1)));
252 const short min
= SHRT_MIN
;
253 const short max
= SHRT_MAX
;
255 sink (f_shrt_1 (min
)); /* { dg-warning "argument 1 value .-\[0-9\]+. is negative" } */
256 sink (f_shrt_1 (-1)); /* { dg-warning "argument 1 value .-1. is negative" } */
259 sink (f_shrt_1 (max
));
263 test_shrt_range (short n
)
265 const short min
= SHRT_MIN
;
266 const short max
= SHRT_MAX
;
270 sink (f_shrt_1 (SR (min
, min
+ 1))); /* { dg-warning "argument 1 range \\\[-\[0-9\]+, -\[0-9\]+\\\] is negative" } */
271 sink (f_shrt_1 (SR (min
, 0))); /* { dg-warning "argument 1 range \\\[-\[0-9\]+, 0\\\] is negative" } */
272 sink (f_shrt_1 (SR (-1, 0))); /* { dg-warning "argument 1 range \\\[-1, 0\\\] is negative" } */
273 sink (f_shrt_1 (SR (-1, 1)));
274 sink (f_shrt_1 (SR (0, 1)));
275 sink (f_shrt_1 (SR (0, max
- 1)));
276 sink (f_shrt_1 (SR (1, max
)));
277 sink (f_shrt_1 (SR (max
- 1, max
)));
283 const unsigned max
= UINT_MAX
;
290 sink (f_uint_1 (max
- 1));
291 sink (f_uint_1 (max
));
296 test_uint_range (unsigned n
)
298 const unsigned max
= UINT_MAX
;
301 sink (f_uint_1 (UR (0, 1)));
302 sink (f_uint_1 (UR (0, max
- 1)));
303 sink (f_uint_1 (UR (1, max
- 1)));
304 sink (f_uint_1 (UR (1, max
)));
310 const int min
= INT_MIN
;
311 const int max
= INT_MAX
;
313 sink (f_int_1 (min
)); /* { dg-warning "argument 1 value .-\[0-9\]+. is negative" } */
314 sink (f_int_1 (-1)); /* { dg-warning "argument 1 value .-1. is negative" } */
317 sink (f_int_1 (max
));
321 test_int_range (int n
)
323 const int min
= INT_MIN
;
324 const int max
= INT_MAX
;
328 sink (f_int_1 (SR (min
, min
+ 1))); /* { dg-warning "argument 1 range \\\[-\[0-9\]+, -\[0-9\]+\\\] is negative" } */
329 sink (f_int_1 (SR (min
, 0))); /* { dg-warning "argument 1 range \\\[-\[0-9\]+, 0\\\] is negative" } */
330 sink (f_int_1 (SR (-1, 0))); /* { dg-warning "argument 1 range \\\[-1, 0\\\] is negative" } */
331 sink (f_int_1 (SR (-1, 1)));
332 sink (f_int_1 (SR (0, 1)));
333 sink (f_int_1 (SR (0, max
- 1)));
334 sink (f_int_1 (SR (1, max
)));
335 sink (f_int_1 (SR (max
- 1, max
)));
339 test_ulong_cst (void)
341 const unsigned long max
= ULONG_MAX
;
343 sink (f_ulong_1 (0));
344 sink (f_ulong_1 (1));
345 #if ULONG_MAX < SIZE_MAX
346 sink (f_ulong_1 (max
- 1));
347 sink (f_ulong_1 (max
));
354 test_ulong_range (unsigned long n
)
356 const unsigned long max
= ULONG_MAX
;
358 sink (f_ulong_1 (n
));
359 sink (f_ulong_1 (UR (0, 1)));
360 sink (f_ulong_1 (UR (0, max
- 1)));
361 sink (f_ulong_1 (UR (1, max
- 1)));
362 sink (f_ulong_1 (UR (1, max
)));
368 const long min
= LONG_MIN
;
369 const long max
= LONG_MAX
;
371 sink (f_long_1 (min
)); /* { dg-warning "argument 1 value .-\[0-9\]+l*. is negative" } */
372 sink (f_long_1 (-1)); /* { dg-warning "argument 1 value .-1l*. is negative" } */
375 sink (f_long_1 (max
));
379 test_long_range (long n
)
381 const long min
= LONG_MIN
;
382 const long max
= LONG_MAX
;
386 sink (f_long_1 (SR (min
, min
+ 1))); /* { dg-warning "argument 1 range \\\[-\[0-9\]+l*, -\[0-9\]+l*\\\] is negative" } */
387 sink (f_long_1 (SR (min
, 0))); /* { dg-warning "argument 1 range \\\[-\[0-9\]+l*, 0l*\\\] is negative" } */
388 sink (f_long_1 (SR (-1, 0))); /* { dg-warning "argument 1 range \\\[-1l*, 0l*\\\] is negative" } */
389 sink (f_long_1 (SR (-1, 1)));
390 sink (f_long_1 (SR (0, 1)));
391 sink (f_long_1 (SR (0, max
- 1)));
392 sink (f_long_1 (SR (1, max
)));
393 sink (f_long_1 (SR (max
- 1, max
)));
399 const size_t max
= __SIZE_MAX__
;
403 sink (f_size_1 (max
- 1)); /* { dg-warning "argument 1 value .\[0-9\]+. exceeds maximum object size \[0-9\]+" } */
404 sink (f_size_1 (max
)); /* { dg-warning "argument 1 value .\[0-9\]+. exceeds maximum object size \[0-9\]+" } */
406 sink (f_size_2 (0, max
- 1)); /* { dg-warning "argument 2 value .\[0-9\]+. exceeds maximum object size \[0-9\]+" } */
407 sink (f_size_2 (max
- 1, 0)); /* { dg-warning "argument 1 value .\[0-9\]+. exceeds maximum object size \[0-9\]+" } */
408 sink (f_size_2 (1, max
- 1)); /* { dg-warning "argument 2 value .\[0-9\]+. exceeds maximum object size \[0-9\]+" } */
409 sink (f_size_2 (max
- 1, 1)); /* { dg-warning "argument 1 value .\[0-9\]+. exceeds maximum object size \[0-9\]+" } */
410 sink (f_size_2 (max
- 1, max
- 1)); /* { dg-warning "argument 1 value .\[0-9\]+. exceeds maximum object size \[0-9\]+" } */
411 /* { dg-warning "argument 2 value .\[0-9\]+. exceeds maximum object size \[0-9\]+" "argument 2" { target *-*-* } .-1 } */
413 sink (f_size_2 (0, max
)); /* { dg-warning "argument 2 value .\[0-9\]+. exceeds maximum object size \[0-9\]+" } */
414 sink (f_size_2 (max
, 0)); /* { dg-warning "argument 1 value .\[0-9\]+. exceeds maximum object size \[0-9\]+" } */
416 sink (f_size_2 (max
/ 2, 2)); /* { dg-warning "product .\[0-9\]+ \\* \[0-9\]+. of arguments 1 and 2 exceeds maximum object size \[0-9\]+" } */
417 sink (f_size_2 (max
/ 2, 3)); /* { dg-warning "product .\[0-9\]+ \\* \[0-9\]+. of arguments 1 and 2 exceeds .SIZE_MAX." } */
421 test_size_range (size_t ui
, ptrdiff_t si
)
423 const ptrdiff_t smin
= PTRDIFF_MIN
;
424 const ptrdiff_t smax
= PTRDIFF_MAX
;
425 const size_t umax
= SIZE_MAX
;
427 sink (f_size_1 (ui
));
428 sink (f_size_1 (si
));
430 sink (f_size_1 (UR (0, 1)));
431 sink (f_size_1 (UR (0, umax
- 1)));
432 sink (f_size_1 (UR (1, umax
- 1)));
433 sink (f_size_1 (UR (1, umax
)));
435 sink (f_size_1 (UAR (1, 1)));
436 /* Since the only valid argument in the anti-range below is zero
437 a warning is expected even though -Walloc-zero is not specified. */
438 sink (f_size_1 (UAR (1, umax
/ 2))); /* { dg-warning "argument 1 range \\\[\[0-9\]+, \[0-9\]+\\\] exceeds maximum object size " } */
439 /* The only valid argument in this range is 1. */
440 sink (f_size_1 (UAR (2, umax
/ 2)));
442 sink (f_size_2 (ui
, ui
));
443 sink (f_size_2 (si
, si
));
444 sink (f_size_2 (ui
, umax
/ 2));
445 sink (f_size_2 (si
, umax
/ 2));
446 sink (f_size_2 (umax
/ 2, ui
));
447 sink (f_size_2 (umax
/ 2, si
));
449 sink (f_size_2 (UR (0, 1), umax
)); /* { dg-warning "argument 2 value .\[0-9\]+. exceeds maximum object size " } */
450 sink (f_size_2 (UR (0, 1), umax
/ 2));
451 sink (f_size_2 (UR (0, umax
/ 2), umax
/ 2));
453 sink (f_size_2 (UR (umax
/ 2 + 1, umax
/ 2 + 2), ui
)); /* { dg-warning "argument 1 range \\\[\[0-9\]+, \[0-9\]+\\\] exceeds maximum object size " } */
454 sink (f_size_2 (ui
, UR (umax
/ 2 + 1, umax
/ 2 + 2))); /* { dg-warning "argument 2 range \\\[\[0-9\]+, \[0-9\]+\\\] exceeds maximum object size " } */
455 sink (f_size_2 (UR (umax
/ 2 + 1, umax
), UR (umax
/ 2 + 1, umax
))); /* { dg-warning "argument 1 range \\\[\[0-9\]+, \[0-9\]+\\\] exceeds maximum object size " } */
456 /* { dg-warning "argument 2 range \\\[\[0-9\]+, \[0-9\]+\\\] exceeds maximum object size " "argument 2" { target *-*-* } .-1 } */
458 sink (f_size_2 (SR (smin
, 1), 1));
459 sink (f_size_2 (SR (smin
, 1), umax
/ 2));
460 sink (f_size_2 (SR (-1, smax
), 1));
461 sink (f_size_2 (SR (-1, smax
), umax
/ 2));
462 sink (f_size_2 (SR (-1, 1), 1));
463 sink (f_size_2 (SR (-1, 1), umax
/ 2));
464 sink (f_size_2 (SR (-9, 9), 1));
465 sink (f_size_2 (SR (-9, 9), umax
/ 2));