malloc.c revision 15d0ae170c2037815b6383c532253585fcd3d04e
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,experimental.core.CastSize,experimental.unix.Malloc -analyzer-store=region -verify %s 2#include "system-header-simulator.h" 3 4typedef __typeof(sizeof(int)) size_t; 5void *malloc(size_t); 6void free(void *); 7void *realloc(void *ptr, size_t size); 8void *calloc(size_t nmemb, size_t size); 9 10void myfoo(int *p); 11void myfooint(int p); 12 13void f1() { 14 int *p = malloc(12); 15 return; // expected-warning{{Allocated memory never released. Potential memory leak.}} 16} 17 18void f2() { 19 int *p = malloc(12); 20 free(p); 21 free(p); // expected-warning{{Try to free a memory block that has been released}} 22} 23 24void f2_realloc_0() { 25 int *p = malloc(12); 26 realloc(p,0); 27 realloc(p,0); // expected-warning{{Try to free a memory block that has been released}} 28} 29 30void f2_realloc_1() { 31 int *p = malloc(12); 32 int *q = realloc(p,0); // no-warning 33} 34 35// This case tests that storing malloc'ed memory to a static variable which is 36// then returned is not leaked. In the absence of known contracts for functions 37// or inter-procedural analysis, this is a conservative answer. 38int *f3() { 39 static int *p = 0; 40 p = malloc(12); 41 return p; // no-warning 42} 43 44// This case tests that storing malloc'ed memory to a static global variable 45// which is then returned is not leaked. In the absence of known contracts for 46// functions or inter-procedural analysis, this is a conservative answer. 47static int *p_f4 = 0; 48int *f4() { 49 p_f4 = malloc(12); 50 return p_f4; // no-warning 51} 52 53int *f5() { 54 int *q = malloc(12); 55 q = realloc(q, 20); 56 return q; // no-warning 57} 58 59void f6() { 60 int *p = malloc(12); 61 if (!p) 62 return; // no-warning 63 else 64 free(p); 65} 66 67void f6_realloc() { 68 int *p = malloc(12); 69 if (!p) 70 return; // no-warning 71 else 72 realloc(p,0); 73} 74 75 76char *doit2(); 77void pr6069() { 78 char *buf = doit2(); 79 free(buf); 80} 81 82void pr6293() { 83 free(0); 84} 85 86void f7() { 87 char *x = (char*) malloc(4); 88 free(x); 89 x[0] = 'a'; // expected-warning{{Use of dynamically allocated memory after it is freed.}} 90} 91 92void f7_realloc() { 93 char *x = (char*) malloc(4); 94 realloc(x,0); 95 x[0] = 'a'; // expected-warning{{Use of dynamically allocated memory after it is freed.}} 96} 97 98void PR6123() { 99 int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}} 100} 101 102void PR7217() { 103 int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}} 104 buf[1] = 'c'; // not crash 105} 106 107void mallocCastToVoid() { 108 void *p = malloc(2); 109 const void *cp = p; // not crash 110 free(p); 111} 112 113void mallocCastToFP() { 114 void *p = malloc(2); 115 void (*fp)() = p; // not crash 116 free(p); 117} 118 119// This tests that malloc() buffers are undefined by default 120char mallocGarbage () { 121 char *buf = malloc(2); 122 char result = buf[1]; // expected-warning{{undefined}} 123 free(buf); 124 return result; 125} 126 127// This tests that calloc() buffers need to be freed 128void callocNoFree () { 129 char *buf = calloc(2,2); 130 return; // expected-warning{{never released}} 131} 132 133// These test that calloc() buffers are zeroed by default 134char callocZeroesGood () { 135 char *buf = calloc(2,2); 136 char result = buf[3]; // no-warning 137 if (buf[1] == 0) { 138 free(buf); 139 } 140 return result; // no-warning 141} 142 143char callocZeroesBad () { 144 char *buf = calloc(2,2); 145 char result = buf[3]; // no-warning 146 if (buf[1] != 0) { 147 free(buf); // expected-warning{{never executed}} 148 } 149 return result; // expected-warning{{never released}} 150} 151 152void nullFree() { 153 int *p = 0; 154 free(p); // no warning - a nop 155} 156 157void paramFree(int *p) { 158 myfoo(p); 159 free(p); // no warning 160 myfoo(p); // TODO: This should be a warning. 161} 162 163int* mallocEscapeRet() { 164 int *p = malloc(12); 165 return p; // no warning 166} 167 168void mallocEscapeFoo() { 169 int *p = malloc(12); 170 myfoo(p); 171 return; // no warning 172} 173 174void mallocEscapeFree() { 175 int *p = malloc(12); 176 myfoo(p); 177 free(p); 178} 179 180void mallocEscapeFreeFree() { 181 int *p = malloc(12); 182 myfoo(p); 183 free(p); 184 free(p); // expected-warning{{Try to free a memory block that has been released}} 185} 186 187void mallocEscapeFreeUse() { 188 int *p = malloc(12); 189 myfoo(p); 190 free(p); 191 myfoo(p); // expected-warning{{Use of dynamically allocated memory after it is freed.}} 192} 193 194int *myalloc(); 195void myalloc2(int **p); 196 197void mallocEscapeFreeCustomAlloc() { 198 int *p = malloc(12); 199 myfoo(p); 200 free(p); 201 p = myalloc(); 202 free(p); // no warning 203} 204 205void mallocEscapeFreeCustomAlloc2() { 206 int *p = malloc(12); 207 myfoo(p); 208 free(p); 209 myalloc2(&p); 210 free(p); // no warning 211} 212 213void mallocBindFreeUse() { 214 int *x = malloc(12); 215 int *y = x; 216 free(y); 217 myfoo(x); // expected-warning{{Use of dynamically allocated memory after it is freed.}} 218} 219 220void mallocEscapeMalloc() { 221 int *p = malloc(12); 222 myfoo(p); 223 p = malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak.}} 224} 225 226void mallocMalloc() { 227 int *p = malloc(12); 228 p = malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak}} 229} 230 231void mallocFreeMalloc() { 232 int *p = malloc(12); 233 free(p); 234 p = malloc(12); 235 free(p); 236} 237 238void mallocFreeUse_params() { 239 int *p = malloc(12); 240 free(p); 241 myfoo(p); //expected-warning{{Use of dynamically allocated memory after it is freed}} 242} 243 244void mallocFreeUse_params2() { 245 int *p = malloc(12); 246 free(p); 247 myfooint(*p); //expected-warning{{Use of dynamically allocated memory after it is freed}} 248} 249 250void mallocFailedOrNot() { 251 int *p = malloc(12); 252 if (!p) 253 free(p); 254 else 255 free(p); 256} 257 258struct StructWithInt { 259 int g; 260}; 261 262int *mallocReturnFreed() { 263 int *p = malloc(12); 264 free(p); 265 return p; // expected-warning {{Use of dynamically allocated}} 266} 267 268int useAfterFreeStruct() { 269 struct StructWithInt *px= malloc(sizeof(struct StructWithInt)); 270 px->g = 5; 271 free(px); 272 return px->g; // expected-warning {{Use of dynamically allocated}} 273} 274 275void nonSymbolAsFirstArg(int *pp, struct StructWithInt *p); 276 277void mallocEscapeFooNonSymbolArg() { 278 struct StructWithInt *p = malloc(sizeof(struct StructWithInt)); 279 nonSymbolAsFirstArg(&p->g, p); 280 return; // no warning 281} 282 283void mallocFailedOrNotLeak() { 284 int *p = malloc(12); 285 if (p == 0) 286 return; // no warning 287 else 288 return; // expected-warning {{Allocated memory never released. Potential memory leak.}} 289} 290 291int *Gl; 292struct GlStTy { 293 int *x; 294}; 295 296struct GlStTy GlS = {0}; 297 298void GlobalFree() { 299 free(Gl); 300} 301 302void GlobalMalloc() { 303 Gl = malloc(12); 304} 305 306void GlobalStructMalloc() { 307 int *a = malloc(12); 308 GlS.x = a; 309} 310 311void GlobalStructMallocFree() { 312 int *a = malloc(12); 313 GlS.x = a; 314 free(GlS.x); 315} 316 317// Region escape testing. 318 319unsigned takePtrToPtr(int **p); 320void PassTheAddrOfAllocatedData(int f) { 321 int *p = malloc(12); 322 // We don't know what happens after the call. Should stop tracking here. 323 if (takePtrToPtr(&p)) 324 f++; 325 free(p); // no warning 326} 327 328struct X { 329 int *p; 330}; 331unsigned takePtrToStruct(struct X *s); 332int ** foo2(int *g, int f) { 333 int *p = malloc(12); 334 struct X *px= malloc(sizeof(struct X)); 335 px->p = p; 336 // We don't know what happens after this call. Should not track px nor p. 337 if (takePtrToStruct(px)) 338 f++; 339 free(p); 340 return 0; 341} 342 343struct X* RegInvalidationDetect1(struct X *s2) { 344 struct X *px= malloc(sizeof(struct X)); 345 px->p = 0; 346 px = s2; 347 return px; // expected-warning {{Allocated memory never released. Potential memory leak.}} 348} 349 350struct X* RegInvalidationGiveUp1() { 351 int *p = malloc(12); 352 struct X *px= malloc(sizeof(struct X)); 353 px->p = p; 354 return px; 355} 356 357int **RegInvalidationDetect2(int **pp) { 358 int *p = malloc(12); 359 pp = &p; 360 pp++; 361 return 0;// expected-warning {{Allocated memory never released. Potential memory leak.}} 362} 363 364extern void exit(int) __attribute__ ((__noreturn__)); 365void mallocExit(int *g) { 366 struct xx *p = malloc(12); 367 if (g != 0) 368 exit(1); 369 free(p); 370 return; 371} 372 373extern void __assert_fail (__const char *__assertion, __const char *__file, 374 unsigned int __line, __const char *__function) 375 __attribute__ ((__noreturn__)); 376#define assert(expr) \ 377 ((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__)) 378void mallocAssert(int *g) { 379 struct xx *p = malloc(12); 380 381 assert(g != 0); 382 free(p); 383 return; 384} 385 386void doNotInvalidateWhenPassedToSystemCalls(char *s) { 387 char *p = malloc(12); 388 strlen(p); 389 strcpy(p, s); // expected-warning {{leak}} 390} 391 392// Below are the known false positives. 393 394// TODO: There should be no warning here. 395void reallocFails(int *g, int f) { 396 char *p = malloc(12); 397 char *r = realloc(p, 12+1); 398 if (!r) { 399 free(p); // expected-warning {{Try to free a memory block that has been released}} 400 } else { 401 free(r); 402 } 403} 404 405// TODO: There should be no warning here. This one might be difficult to get rid of. 406void dependsOnValueOfPtr(int *g, unsigned f) { 407 int *p; 408 409 if (f) { 410 p = g; 411 } else { 412 p = malloc(12); 413 } 414 415 if (p != g) 416 free(p); 417 else 418 return; // expected-warning{{Allocated memory never released. Potential memory leak}} 419 return; 420} 421 422// TODO: Should this be a warning? 423// Here we are returning a pointer one past the allocated value. An idiom which 424// can be used for implementing special malloc. The correct uses of this might 425// be rare enough so that we could keep this as a warning. 426static void *specialMalloc(int n){ 427 int *p; 428 p = malloc( n+8 ); 429 if( p ){ 430 p[0] = n; 431 p++; 432 } 433 return p;// expected-warning {{Allocated memory never released. Potential memory leak.}} 434} 435