Anna Zaks | ca11510 | 2012-05-07 23:30:29 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -analyze -analyzer-checker=unix.MallocSizeof -verify %s |
Peter Collingbourne | dc30967 | 2011-12-08 08:31:14 +0000 | [diff] [blame] | 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); |
Ted Kremenek | 88db6a2 | 2012-05-01 00:10:19 +0000 | [diff] [blame] | 8 | void free(void *ptr); |
Peter Collingbourne | dc30967 | 2011-12-08 08:31:14 +0000 | [diff] [blame] | 9 | |
| 10 | struct A {}; |
| 11 | struct B {}; |
| 12 | |
Anna Zaks | 2e336ac | 2012-06-08 18:44:43 +0000 | [diff] [blame] | 13 | void foo(unsigned int unsignedInt, unsigned int readSize) { |
Peter Collingbourne | dc30967 | 2011-12-08 08:31:14 +0000 | [diff] [blame] | 14 | int *ip1 = malloc(sizeof(1)); |
| 15 | int *ip2 = malloc(4 * sizeof(int)); |
| 16 | |
Anna Zaks | ca11510 | 2012-05-07 23:30:29 +0000 | [diff] [blame] | 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'}} |
Anna Zaks | 2e336ac | 2012-06-08 18:44:43 +0000 | [diff] [blame] | 19 | char *cp3 = malloc(5 * sizeof(char) + 2); // no warning |
| 20 | unsigned char *buf = malloc(readSize + sizeof(unsignedInt)); // no warning |
Peter Collingbourne | dc30967 | 2011-12-08 08:31:14 +0000 | [diff] [blame] | 21 | |
| 22 | struct A *ap1 = calloc(1, sizeof(struct A)); |
| 23 | struct A *ap2 = calloc(2, sizeof(*ap1)); |
Anna Zaks | ca11510 | 2012-05-07 23:30:29 +0000 | [diff] [blame] | 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'}} |
Peter Collingbourne | dc30967 | 2011-12-08 08:31:14 +0000 | [diff] [blame] | 27 | struct A *ap6 = realloc(ap5, sizeof(struct A)); |
Anna Zaks | ca11510 | 2012-05-07 23:30:29 +0000 | [diff] [blame] | 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'}} |
Peter Collingbourne | dc30967 | 2011-12-08 08:31:14 +0000 | [diff] [blame] | 29 | } |
Ted Kremenek | 88db6a2 | 2012-05-01 00:10:19 +0000 | [diff] [blame] | 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 |
Anna Zaks | ca11510 | 2012-05-07 23:30:29 +0000 | [diff] [blame] | 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 *'}} |
Ted Kremenek | 88db6a2 | 2012-05-01 00:10:19 +0000 | [diff] [blame] | 35 | free(x); |
| 36 | } |
Anna Zaks | 258bd59 | 2012-09-07 19:20:13 +0000 | [diff] [blame] | 37 | |
| 38 | int *mallocArraySize() { |
| 39 | static const int sTable[10]; |
Anna Zaks | 9f6ec82 | 2012-09-08 00:09:02 +0000 | [diff] [blame] | 40 | static const int nestedTable[10][2]; |
Anna Zaks | 258bd59 | 2012-09-07 19:20:13 +0000 | [diff] [blame] | 41 | int *table = malloc(sizeof sTable); |
| 42 | int *table1 = malloc(sizeof nestedTable); |
Anna Zaks | 9f6ec82 | 2012-09-08 00:09:02 +0000 | [diff] [blame] | 43 | int (*table2)[2] = malloc(sizeof nestedTable); |
| 44 | int (*table3)[10][2] = malloc(sizeof nestedTable); |
Anna Zaks | 258bd59 | 2012-09-07 19:20:13 +0000 | [diff] [blame] | 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 | } |