1 | // RUN: %clang_analyze_cc1 -analyzer-checker=unix.MallocSizeof -verify %s |
2 | |
3 | #include <stddef.h> |
4 | |
5 | void *malloc(size_t size); |
6 | void *calloc(size_t nmemb, size_t size); |
7 | void *realloc(void *ptr, size_t size); |
8 | void free(void *ptr); |
9 | |
10 | struct A {}; |
11 | struct B {}; |
12 | |
13 | void foo(unsigned int unsignedInt, unsigned int readSize) { |
14 | int *ip1 = malloc(sizeof(1)); |
15 | int *ip2 = malloc(4 * sizeof(int)); |
16 | |
17 | long *lp1 = malloc(sizeof(short)); // expected-warning {{Result of 'malloc' is converted to a pointer of type 'long', which is incompatible with sizeof operand type 'short'}} |
18 | long *lp2 = malloc(5 * sizeof(double)); // expected-warning {{Result of 'malloc' is converted to a pointer of type 'long', which is incompatible with sizeof operand type 'double'}} |
19 | char *cp3 = malloc(5 * sizeof(char) + 2); // no warning |
20 | unsigned char *buf = malloc(readSize + sizeof(unsignedInt)); // no warning |
21 | |
22 | struct A *ap1 = calloc(1, sizeof(struct A)); |
23 | struct A *ap2 = calloc(2, sizeof(*ap1)); |
24 | struct A *ap3 = calloc(2, sizeof(ap1)); // expected-warning {{Result of 'calloc' is converted to a pointer of type 'struct A', which is incompatible with sizeof operand type 'struct A *'}} |
25 | struct A *ap4 = calloc(3, sizeof(struct A*)); // expected-warning {{Result of 'calloc' is converted to a pointer of type 'struct A', which is incompatible with sizeof operand type 'struct A *'}} |
26 | struct A *ap5 = calloc(4, sizeof(struct B)); // expected-warning {{Result of 'calloc' is converted to a pointer of type 'struct A', which is incompatible with sizeof operand type 'struct B'}} |
27 | struct A *ap6 = realloc(ap5, sizeof(struct A)); |
28 | struct A *ap7 = realloc(ap5, sizeof(struct B)); // expected-warning {{Result of 'realloc' is converted to a pointer of type 'struct A', which is incompatible with sizeof operand type 'struct B'}} |
29 | } |
30 | |
31 | // Don't warn when the types differ only by constness. |
32 | void ignore_const() { |
33 | const char **x = (const char **)malloc(1 * sizeof(char *)); // no-warning |
34 | const char ***y = (const char ***)malloc(1 * sizeof(char *)); // expected-warning {{Result of 'malloc' is converted to a pointer of type 'const char **', which is incompatible with sizeof operand type 'char *'}} |
35 | free(x); |
36 | } |
37 | |
38 | int *mallocArraySize() { |
39 | static const int sTable[10]; |
40 | static const int nestedTable[10][2]; |
41 | int *table = malloc(sizeof sTable); |
42 | int *table1 = malloc(sizeof nestedTable); |
43 | int (*table2)[2] = malloc(sizeof nestedTable); |
44 | int (*table3)[10][2] = malloc(sizeof nestedTable); |
45 | return table; |
46 | } |
47 | |
48 | int *mallocWrongArraySize() { |
49 | static const double sTable[10]; |
50 | int *table = malloc(sizeof sTable); // expected-warning {{Result of 'malloc' is converted to a pointer of type 'int', which is incompatible with sizeof operand type 'const double [10]'}} |
51 | return table; |
52 | } |
53 | |