1 | // RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -analyzer-checker=alpha.security.MallocOverflow,unix -verify %s |
2 | // RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -analyzer-checker=alpha.security.MallocOverflow,unix,optin.portability -DPORTABILITY -verify %s |
3 | |
4 | typedef __typeof__(sizeof(int)) size_t; |
5 | extern void *malloc(size_t); |
6 | extern void free(void *ptr); |
7 | |
8 | void *malloc(unsigned long s); |
9 | |
10 | struct table { |
11 | int nentry; |
12 | unsigned *table; |
13 | unsigned offset_max; |
14 | }; |
15 | |
16 | static int table_build(struct table *t) { |
17 | |
18 | t->nentry = ((t->offset_max >> 2) + 31) / 32; |
19 | t->table = (unsigned *)malloc(sizeof(unsigned) * t->nentry); // expected-warning {{the computation of the size of the memory allocation may overflow}} |
20 | |
21 | int n; |
22 | n = 10000; |
23 | int *p = malloc(sizeof(int) * n); // no-warning |
24 | |
25 | free(p); |
26 | return t->nentry; |
27 | } |
28 | |
29 | static int table_build_1(struct table *t) { |
30 | t->nentry = (sizeof(struct table) * 2 + 31) / 32; |
31 | t->table = (unsigned *)malloc(sizeof(unsigned) * t->nentry); // no-warning |
32 | return t->nentry; |
33 | } |
34 | |
35 | void *f(int n) { |
36 | return malloc(n * 0 * sizeof(int)); |
37 | #ifdef PORTABILITY |
38 | // expected-warning@-2{{Call to 'malloc' has an allocation size of 0 bytes}} |
39 | #endif |
40 | } |
41 | |