malloc.c revision 6dd4dffe1090e820e9b5b25eee8ad3907a1aa679
1// RUN: %clang_cc1 -analyze -analyzer-checker=core.experimental.UnreachableCode,core.experimental.CastSize,core.experimental.Malloc -analyzer-check-objc-mem -analyzer-store=region -verify %s 2typedef __typeof(sizeof(int)) size_t; 3void *malloc(size_t); 4void free(void *); 5void *realloc(void *ptr, size_t size); 6void *calloc(size_t nmemb, size_t size); 7void __attribute((ownership_returns(malloc))) *my_malloc(size_t); 8void __attribute((ownership_takes(malloc, 1))) my_free(void *); 9void __attribute((ownership_returns(malloc, 1))) *my_malloc2(size_t); 10void __attribute((ownership_holds(malloc, 1))) my_hold(void *); 11 12// Duplicate attributes are silly, but not an error. 13// Duplicate attribute has no extra effect. 14// If two are of different kinds, that is an error and reported as such. 15void __attribute((ownership_holds(malloc, 1))) 16__attribute((ownership_holds(malloc, 1))) 17__attribute((ownership_holds(malloc, 3))) my_hold2(void *, void *, void *); 18void *my_malloc3(size_t); 19void *myglobalpointer; 20struct stuff { 21 void *somefield; 22}; 23struct stuff myglobalstuff; 24 25void f1() { 26 int *p = malloc(12); 27 return; // expected-warning{{Allocated memory never released. Potential memory leak.}} 28} 29 30void f2() { 31 int *p = malloc(12); 32 free(p); 33 free(p); // expected-warning{{Try to free a memory block that has been released}} 34} 35 36// ownership attributes tests 37void naf1() { 38 int *p = my_malloc3(12); 39 return; // no-warning 40} 41 42void n2af1() { 43 int *p = my_malloc2(12); 44 return; // expected-warning{{Allocated memory never released. Potential memory leak.}} 45} 46 47void af1() { 48 int *p = my_malloc(12); 49 return; // expected-warning{{Allocated memory never released. Potential memory leak.}} 50} 51 52void af1_b() { 53 int *p = my_malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak.}} 54} 55 56void af1_c() { 57 myglobalpointer = my_malloc(12); // no-warning 58} 59 60void af1_d() { 61 struct stuff mystuff; 62 mystuff.somefield = my_malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak.}} 63} 64 65// Test that we can pass out allocated memory via pointer-to-pointer. 66void af1_e(void **pp) { 67 *pp = my_malloc(42); // no-warning 68} 69 70void af1_f(struct stuff *somestuff) { 71 somestuff->somefield = my_malloc(12); // no-warning 72} 73 74// Allocating memory for a field via multiple indirections to our arguments is OK. 75void af1_g(struct stuff **pps) { 76 *pps = my_malloc(sizeof(struct stuff)); // no-warning 77 (*pps)->somefield = my_malloc(42); // no-warning 78} 79 80void af2() { 81 int *p = my_malloc(12); 82 my_free(p); 83 free(p); // expected-warning{{Try to free a memory block that has been released}} 84} 85 86void af2b() { 87 int *p = my_malloc(12); 88 free(p); 89 my_free(p); // expected-warning{{Try to free a memory block that has been released}} 90} 91 92void af2c() { 93 int *p = my_malloc(12); 94 free(p); 95 my_hold(p); // expected-warning{{Try to free a memory block that has been released}} 96} 97 98void af2d() { 99 int *p = my_malloc(12); 100 free(p); 101 my_hold2(0, 0, p); // expected-warning{{Try to free a memory block that has been released}} 102} 103 104// No leak if malloc returns null. 105void af2e() { 106 int *p = my_malloc(12); 107 if (!p) 108 return; // no-warning 109 free(p); // no-warning 110} 111 112// This case would inflict a double-free elsewhere. 113// However, this case is considered an analyzer bug since it causes false-positives. 114void af3() { 115 int *p = my_malloc(12); 116 my_hold(p); 117 free(p); // no-warning 118} 119 120// This case would inflict a double-free elsewhere. 121// However, this case is considered an analyzer bug since it causes false-positives. 122int * af4() { 123 int *p = my_malloc(12); 124 my_free(p); 125 return p; // no-warning 126} 127 128// This case is (possibly) ok, be conservative 129int * af5() { 130 int *p = my_malloc(12); 131 my_hold(p); 132 return p; // no-warning 133} 134 135 136 137// This case tests that storing malloc'ed memory to a static variable which is 138// then returned is not leaked. In the absence of known contracts for functions 139// or inter-procedural analysis, this is a conservative answer. 140int *f3() { 141 static int *p = 0; 142 p = malloc(12); 143 return p; // no-warning 144} 145 146// This case tests that storing malloc'ed memory to a static global variable 147// which is then returned is not leaked. In the absence of known contracts for 148// functions or inter-procedural analysis, this is a conservative answer. 149static int *p_f4 = 0; 150int *f4() { 151 p_f4 = malloc(12); 152 return p_f4; // no-warning 153} 154 155int *f5() { 156 int *q = malloc(12); 157 q = realloc(q, 20); 158 return q; // no-warning 159} 160 161void f6() { 162 int *p = malloc(12); 163 if (!p) 164 return; // no-warning 165 else 166 free(p); 167} 168 169char *doit2(); 170void pr6069() { 171 char *buf = doit2(); 172 free(buf); 173} 174 175void pr6293() { 176 free(0); 177} 178 179void f7() { 180 char *x = (char*) malloc(4); 181 free(x); 182 x[0] = 'a'; // expected-warning{{Use dynamically allocated memory after it is freed.}} 183} 184 185void PR6123() { 186 int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}} 187} 188 189void PR7217() { 190 int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}} 191 buf[1] = 'c'; // not crash 192} 193 194void mallocCastToVoid() { 195 void *p = malloc(2); 196 const void *cp = p; // not crash 197 free(p); 198} 199 200void mallocCastToFP() { 201 void *p = malloc(2); 202 void (*fp)() = p; // not crash 203 free(p); 204} 205 206// This tests that malloc() buffers are undefined by default 207char mallocGarbage () { 208 char *buf = malloc(2); 209 char result = buf[1]; // expected-warning{{undefined}} 210 free(buf); 211 return result; 212} 213 214// This tests that calloc() buffers need to be freed 215void callocNoFree () { 216 char *buf = calloc(2,2); 217 return; // expected-warning{{never released}} 218} 219 220// These test that calloc() buffers are zeroed by default 221char callocZeroesGood () { 222 char *buf = calloc(2,2); 223 char result = buf[3]; // no-warning 224 if (buf[1] == 0) { 225 free(buf); 226 } 227 return result; // no-warning 228} 229 230char callocZeroesBad () { 231 char *buf = calloc(2,2); 232 char result = buf[3]; // no-warning 233 if (buf[1] != 0) { 234 free(buf); // expected-warning{{never executed}} 235 } 236 return result; // expected-warning{{never released}} 237} 238