malloc.c revision ac593008c2035fa241c80352a0c97c5d853facbf
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 *valloc(size_t); 7void free(void *); 8void *realloc(void *ptr, size_t size); 9void *reallocf(void *ptr, size_t size); 10void *calloc(size_t nmemb, size_t size); 11 12void myfoo(int *p); 13void myfooint(int p); 14char *fooRetPtr(); 15 16void f1() { 17 int *p = malloc(12); 18 return; // expected-warning{{Allocated memory never released. Potential memory leak.}} 19} 20 21void f2() { 22 int *p = malloc(12); 23 free(p); 24 free(p); // expected-warning{{Try to free a memory block that has been released}} 25} 26 27void f2_realloc_0() { 28 int *p = malloc(12); 29 realloc(p,0); 30 realloc(p,0); // expected-warning{{Try to free a memory block that has been released}} 31} 32 33void f2_realloc_1() { 34 int *p = malloc(12); 35 int *q = realloc(p,0); // no-warning 36} 37 38void reallocNotNullPtr(unsigned sizeIn) { 39 unsigned size = 12; 40 char *p = (char*)malloc(size); 41 if (p) { 42 char *q = (char*)realloc(p, sizeIn); 43 char x = *q; // expected-warning {{Allocated memory never released.}} 44 } 45} 46 47int *realloctest1() { 48 int *q = malloc(12); 49 q = realloc(q, 20); 50 return q; // no warning - returning the allocated value 51} 52 53// p should be freed if realloc fails. 54void reallocFails() { 55 char *p = malloc(12); 56 char *r = realloc(p, 12+1); 57 if (!r) { 58 free(p); 59 } else { 60 free(r); 61 } 62} 63 64void reallocSizeZero1() { 65 char *p = malloc(12); 66 char *r = realloc(p, 0); 67 if (!r) { 68 free(p); 69 } else { 70 free(r); 71 } 72} 73 74void reallocSizeZero2() { 75 char *p = malloc(12); 76 char *r = realloc(p, 0); 77 if (!r) { 78 free(p); 79 } else { 80 free(r); 81 } 82 free(p); // expected-warning {{Try to free a memory block that has been released}} 83} 84 85void reallocSizeZero3() { 86 char *p = malloc(12); 87 char *r = realloc(p, 0); 88 free(r); 89} 90 91void reallocSizeZero4() { 92 char *r = realloc(0, 0); 93 free(r); 94} 95 96void reallocSizeZero5() { 97 char *r = realloc(0, 0); 98} 99 100void reallocPtrZero1() { 101 char *r = realloc(0, 12); // expected-warning {{Allocated memory never released.}} 102} 103 104void reallocPtrZero2() { 105 char *r = realloc(0, 12); 106 if (r) 107 free(r); 108} 109 110void reallocPtrZero3() { 111 char *r = realloc(0, 12); 112 free(r); 113} 114 115void reallocRadar6337483_1() { 116 char *buf = malloc(100); 117 buf = (char*)realloc(buf, 0x1000000); 118 if (!buf) { 119 return;// expected-warning {{Allocated memory never released.}} 120 } 121 free(buf); 122} 123 124void reallocRadar6337483_2() { 125 char *buf = malloc(100); 126 char *buf2 = (char*)realloc(buf, 0x1000000); 127 if (!buf2) { // expected-warning {{Allocated memory never released.}} 128 ; 129 } else { 130 free(buf2); 131 } 132} 133 134void reallocRadar6337483_3() { 135 char * buf = malloc(100); 136 char * tmp; 137 tmp = (char*)realloc(buf, 0x1000000); 138 if (!tmp) { 139 free(buf); 140 return; 141 } 142 buf = tmp; 143 free(buf); 144} 145 146void reallocRadar6337483_4() { 147 char *buf = malloc(100); 148 char *buf2 = (char*)realloc(buf, 0x1000000); 149 if (!buf2) { 150 return; // expected-warning {{Allocated memory never released.}} 151 } else { 152 free(buf2); 153 } 154} 155 156int *reallocfTest1() { 157 int *q = malloc(12); 158 q = reallocf(q, 20); 159 return q; // no warning - returning the allocated value 160} 161 162void reallocfRadar6337483_4() { 163 char *buf = malloc(100); 164 char *buf2 = (char*)reallocf(buf, 0x1000000); 165 if (!buf2) { 166 return; // no warning - reallocf frees even on failure 167 } else { 168 free(buf2); 169 } 170} 171 172void reallocfRadar6337483_3() { 173 char * buf = malloc(100); 174 char * tmp; 175 tmp = (char*)reallocf(buf, 0x1000000); 176 if (!tmp) { 177 free(buf); // expected-warning {{Try to free a memory block that has been released}} 178 return; 179 } 180 buf = tmp; 181 free(buf); 182} 183 184void reallocfPtrZero1() { 185 char *r = reallocf(0, 12); // expected-warning {{Allocated memory never released.}} 186} 187 188 189// This case tests that storing malloc'ed memory to a static variable which is 190// then returned is not leaked. In the absence of known contracts for functions 191// or inter-procedural analysis, this is a conservative answer. 192int *f3() { 193 static int *p = 0; 194 p = malloc(12); 195 return p; // no-warning 196} 197 198// This case tests that storing malloc'ed memory to a static global variable 199// which is then returned is not leaked. In the absence of known contracts for 200// functions or inter-procedural analysis, this is a conservative answer. 201static int *p_f4 = 0; 202int *f4() { 203 p_f4 = malloc(12); 204 return p_f4; // no-warning 205} 206 207int *f5() { 208 int *q = malloc(12); 209 q = realloc(q, 20); 210 return q; // no-warning 211} 212 213void f6() { 214 int *p = malloc(12); 215 if (!p) 216 return; // no-warning 217 else 218 free(p); 219} 220 221void f6_realloc() { 222 int *p = malloc(12); 223 if (!p) 224 return; // no-warning 225 else 226 realloc(p,0); 227} 228 229 230char *doit2(); 231void pr6069() { 232 char *buf = doit2(); 233 free(buf); 234} 235 236void pr6293() { 237 free(0); 238} 239 240void f7() { 241 char *x = (char*) malloc(4); 242 free(x); 243 x[0] = 'a'; // expected-warning{{Use of dynamically allocated memory after it is freed.}} 244} 245 246void f7_realloc() { 247 char *x = (char*) malloc(4); 248 realloc(x,0); 249 x[0] = 'a'; // expected-warning{{Use of dynamically allocated memory after it is freed.}} 250} 251 252void PR6123() { 253 int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}} 254} 255 256void PR7217() { 257 int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}} 258 buf[1] = 'c'; // not crash 259} 260 261void mallocCastToVoid() { 262 void *p = malloc(2); 263 const void *cp = p; // not crash 264 free(p); 265} 266 267void mallocCastToFP() { 268 void *p = malloc(2); 269 void (*fp)() = p; // not crash 270 free(p); 271} 272 273// This tests that malloc() buffers are undefined by default 274char mallocGarbage () { 275 char *buf = malloc(2); 276 char result = buf[1]; // expected-warning{{undefined}} 277 free(buf); 278 return result; 279} 280 281// This tests that calloc() buffers need to be freed 282void callocNoFree () { 283 char *buf = calloc(2,2); 284 return; // expected-warning{{never released}} 285} 286 287// These test that calloc() buffers are zeroed by default 288char callocZeroesGood () { 289 char *buf = calloc(2,2); 290 char result = buf[3]; // no-warning 291 if (buf[1] == 0) { 292 free(buf); 293 } 294 return result; // no-warning 295} 296 297char callocZeroesBad () { 298 char *buf = calloc(2,2); 299 char result = buf[3]; // no-warning 300 if (buf[1] != 0) { 301 free(buf); // expected-warning{{never executed}} 302 } 303 return result; // expected-warning{{never released}} 304} 305 306void nullFree() { 307 int *p = 0; 308 free(p); // no warning - a nop 309} 310 311void paramFree(int *p) { 312 myfoo(p); 313 free(p); // no warning 314 myfoo(p); // TODO: This should be a warning. 315} 316 317int* mallocEscapeRet() { 318 int *p = malloc(12); 319 return p; // no warning 320} 321 322void mallocEscapeFoo() { 323 int *p = malloc(12); 324 myfoo(p); 325 return; // no warning 326} 327 328void mallocEscapeFree() { 329 int *p = malloc(12); 330 myfoo(p); 331 free(p); 332} 333 334void mallocEscapeFreeFree() { 335 int *p = malloc(12); 336 myfoo(p); 337 free(p); 338 free(p); // expected-warning{{Try to free a memory block that has been released}} 339} 340 341void mallocEscapeFreeUse() { 342 int *p = malloc(12); 343 myfoo(p); 344 free(p); 345 myfoo(p); // expected-warning{{Use of dynamically allocated memory after it is freed.}} 346} 347 348int *myalloc(); 349void myalloc2(int **p); 350 351void mallocEscapeFreeCustomAlloc() { 352 int *p = malloc(12); 353 myfoo(p); 354 free(p); 355 p = myalloc(); 356 free(p); // no warning 357} 358 359void mallocEscapeFreeCustomAlloc2() { 360 int *p = malloc(12); 361 myfoo(p); 362 free(p); 363 myalloc2(&p); 364 free(p); // no warning 365} 366 367void mallocBindFreeUse() { 368 int *x = malloc(12); 369 int *y = x; 370 free(y); 371 myfoo(x); // expected-warning{{Use of dynamically allocated memory after it is freed.}} 372} 373 374void mallocEscapeMalloc() { 375 int *p = malloc(12); 376 myfoo(p); 377 p = malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak.}} 378} 379 380void mallocMalloc() { 381 int *p = malloc(12); 382 p = malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak}} 383} 384 385void mallocFreeMalloc() { 386 int *p = malloc(12); 387 free(p); 388 p = malloc(12); 389 free(p); 390} 391 392void mallocFreeUse_params() { 393 int *p = malloc(12); 394 free(p); 395 myfoo(p); //expected-warning{{Use of dynamically allocated memory after it is freed}} 396} 397 398void mallocFreeUse_params2() { 399 int *p = malloc(12); 400 free(p); 401 myfooint(*p); //expected-warning{{Use of dynamically allocated memory after it is freed}} 402} 403 404void mallocFailedOrNot() { 405 int *p = malloc(12); 406 if (!p) 407 free(p); 408 else 409 free(p); 410} 411 412struct StructWithInt { 413 int g; 414}; 415 416int *mallocReturnFreed() { 417 int *p = malloc(12); 418 free(p); 419 return p; // expected-warning {{Use of dynamically allocated}} 420} 421 422int useAfterFreeStruct() { 423 struct StructWithInt *px= malloc(sizeof(struct StructWithInt)); 424 px->g = 5; 425 free(px); 426 return px->g; // expected-warning {{Use of dynamically allocated}} 427} 428 429void nonSymbolAsFirstArg(int *pp, struct StructWithInt *p); 430 431void mallocEscapeFooNonSymbolArg() { 432 struct StructWithInt *p = malloc(sizeof(struct StructWithInt)); 433 nonSymbolAsFirstArg(&p->g, p); 434 return; // no warning 435} 436 437void mallocFailedOrNotLeak() { 438 int *p = malloc(12); 439 if (p == 0) 440 return; // no warning 441 else 442 return; // expected-warning {{Allocated memory never released. Potential memory leak.}} 443} 444 445void mallocAssignment() { 446 char *p = malloc(12); 447 p = fooRetPtr(); // expected-warning {{leak}} 448} 449 450int vallocTest() { 451 char *mem = valloc(12); 452 return 0; // expected-warning {{Allocated memory never released. Potential memory leak.}} 453} 454 455void vallocEscapeFreeUse() { 456 int *p = valloc(12); 457 myfoo(p); 458 free(p); 459 myfoo(p); // expected-warning{{Use of dynamically allocated memory after it is freed.}} 460} 461 462int *Gl; 463struct GlStTy { 464 int *x; 465}; 466 467struct GlStTy GlS = {0}; 468 469void GlobalFree() { 470 free(Gl); 471} 472 473void GlobalMalloc() { 474 Gl = malloc(12); 475} 476 477void GlobalStructMalloc() { 478 int *a = malloc(12); 479 GlS.x = a; 480} 481 482void GlobalStructMallocFree() { 483 int *a = malloc(12); 484 GlS.x = a; 485 free(GlS.x); 486} 487 488// Make sure that we properly handle a pointer stored into a local struct/array. 489typedef struct _StructWithPtr { 490 int *memP; 491} StructWithPtr; 492 493static StructWithPtr arrOfStructs[10]; 494 495void testMalloc() { 496 int *x = malloc(12); 497 StructWithPtr St; 498 St.memP = x; 499 arrOfStructs[0] = St; 500} 501 502StructWithPtr testMalloc2() { 503 int *x = malloc(12); 504 StructWithPtr St; 505 St.memP = x; 506 return St; 507} 508 509int *testMalloc3() { 510 int *x = malloc(12); 511 int *y = x; 512 return y; 513} 514 515// Region escape testing. 516 517unsigned takePtrToPtr(int **p); 518void PassTheAddrOfAllocatedData(int f) { 519 int *p = malloc(12); 520 // We don't know what happens after the call. Should stop tracking here. 521 if (takePtrToPtr(&p)) 522 f++; 523 free(p); // no warning 524} 525 526struct X { 527 int *p; 528}; 529unsigned takePtrToStruct(struct X *s); 530int ** foo2(int *g, int f) { 531 int *p = malloc(12); 532 struct X *px= malloc(sizeof(struct X)); 533 px->p = p; 534 // We don't know what happens after this call. Should not track px nor p. 535 if (takePtrToStruct(px)) 536 f++; 537 free(p); 538 return 0; 539} 540 541struct X* RegInvalidationDetect1(struct X *s2) { 542 struct X *px= malloc(sizeof(struct X)); 543 px->p = 0; 544 px = s2; 545 return px; // expected-warning {{Allocated memory never released. Potential memory leak.}} 546} 547 548struct X* RegInvalidationGiveUp1() { 549 int *p = malloc(12); 550 struct X *px= malloc(sizeof(struct X)); 551 px->p = p; 552 return px; 553} 554 555int **RegInvalidationDetect2(int **pp) { 556 int *p = malloc(12); 557 pp = &p; 558 pp++; 559 return 0;// expected-warning {{Allocated memory never released. Potential memory leak.}} 560} 561 562extern void exit(int) __attribute__ ((__noreturn__)); 563void mallocExit(int *g) { 564 struct xx *p = malloc(12); 565 if (g != 0) 566 exit(1); 567 free(p); 568 return; 569} 570 571extern void __assert_fail (__const char *__assertion, __const char *__file, 572 unsigned int __line, __const char *__function) 573 __attribute__ ((__noreturn__)); 574#define assert(expr) \ 575 ((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__)) 576void mallocAssert(int *g) { 577 struct xx *p = malloc(12); 578 579 assert(g != 0); 580 free(p); 581 return; 582} 583 584void doNotInvalidateWhenPassedToSystemCalls(char *s) { 585 char *p = malloc(12); 586 strlen(p); 587 strcpy(p, s); // expected-warning {{leak}} 588} 589 590// Below are the known false positives. 591 592// TODO: There should be no warning here. This one might be difficult to get rid of. 593void dependsOnValueOfPtr(int *g, unsigned f) { 594 int *p; 595 596 if (f) { 597 p = g; 598 } else { 599 p = malloc(12); 600 } 601 602 if (p != g) 603 free(p); 604 else 605 return; // expected-warning{{Allocated memory never released. Potential memory leak}} 606 return; 607} 608 609// TODO: Should this be a warning? 610// Here we are returning a pointer one past the allocated value. An idiom which 611// can be used for implementing special malloc. The correct uses of this might 612// be rare enough so that we could keep this as a warning. 613static void *specialMalloc(int n){ 614 int *p; 615 p = malloc( n+8 ); 616 if( p ){ 617 p[0] = n; 618 p++; 619 } 620 return p;// expected-warning {{Allocated memory never released. Potential memory leak.}} 621} 622 623// TODO: This is a false positve that should be fixed by making CString checker smarter. 624void symbolLostWithStrcpy(char *s) { 625 char *p = malloc(12); 626 p = strcpy(p, s); 627 free(p);// expected-warning {{leak}} 628} 629 630// False negatives. 631 632// TODO: This requires tracking symbols stored inside the structs/arrays. 633void testMalloc5() { 634 StructWithPtr St; 635 StructWithPtr *pSt = &St; 636 pSt->memP = malloc(12); 637} 638