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