2018-05-15 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / testsuite / gcc.dg / attr-alloc_size-3.c
blob96ff077ef20f3208d22164a3f6e9a56e24faaf53
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);
68 static size_t
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;
74 return val;
77 static long long
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;
83 return val;
86 static size_t
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)
92 val = min - 1;
93 return val;
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)
103 void sink (void*);
105 void
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));
123 void
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)));
159 void
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" } */
178 void
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));
217 void
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));
237 void
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)));
249 void
250 test_shrt_cst (void)
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" } */
257 sink (f_shrt_1 (0));
258 sink (f_shrt_1 (1));
259 sink (f_shrt_1 (max));
262 void
263 test_shrt_range (short n)
265 const short min = SHRT_MIN;
266 const short max = SHRT_MAX;
268 sink (f_shrt_1 (n));
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)));
280 void
281 test_uint_cst (void)
283 const unsigned max = UINT_MAX;
285 sink (f_uint_1 (0));
286 sink (f_uint_1 (1));
288 if (max < SIZE_MAX)
290 sink (f_uint_1 (max - 1));
291 sink (f_uint_1 (max));
295 void
296 test_uint_range (unsigned n)
298 const unsigned max = UINT_MAX;
300 sink (f_uint_1 (n));
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)));
307 void
308 test_int_cst (void)
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" } */
315 sink (f_int_1 (0));
316 sink (f_int_1 (1));
317 sink (f_int_1 (max));
320 void
321 test_int_range (int n)
323 const int min = INT_MIN;
324 const int max = INT_MAX;
326 sink (f_int_1 (n));
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)));
338 void
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));
348 #else
349 (void)&max;
350 #endif
353 void
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)));
365 void
366 test_long_cst (void)
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" } */
373 sink (f_long_1 (0));
374 sink (f_long_1 (1));
375 sink (f_long_1 (max));
378 void
379 test_long_range (long n)
381 const long min = LONG_MIN;
382 const long max = LONG_MAX;
384 sink (f_long_1 (n));
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)));
396 void
397 test_size_cst (void)
399 const size_t max = __SIZE_MAX__;
401 sink (f_size_1 (0));
402 sink (f_size_1 (1));
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." } */
420 void
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));