malloc.c revision bb2a6864f111e13f7905725963649c60c60bf18b
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,experimental.core.CastSize,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{{Memory is never released; potential memory leak}} 19} 20 21void f2() { 22 int *p = malloc(12); 23 free(p); 24 free(p); // expected-warning{{Attempt to free released memory}} 25} 26 27void f2_realloc_0() { 28 int *p = malloc(12); 29 realloc(p,0); 30 realloc(p,0); // expected-warning{{Attempt to free released memory}} 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 {{Memory is never released; potential memory leak}} 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 {{Attempt to free released memory}} 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 {{Memory is never released; potential memory leak}} 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 {{Memory is never released; potential memory leak}} 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 {{Memory is never released; potential memory leak}} 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 {{Memory is never released; potential memory leak}} 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 {{Attempt to free released memory}} 178 return; 179 } 180 buf = tmp; 181 free(buf); 182} 183 184void reallocfPtrZero1() { 185 char *r = reallocf(0, 12); // expected-warning {{Memory is never released; potential memory leak}} 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 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 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{{Attempt to free released memory}} 339} 340 341void mallocEscapeFreeUse() { 342 int *p = malloc(12); 343 myfoo(p); 344 free(p); 345 myfoo(p); // expected-warning{{Use of 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 memory after it is freed}} 372} 373 374void mallocEscapeMalloc() { 375 int *p = malloc(12); 376 myfoo(p); 377 p = malloc(12); // expected-warning{{Memory is never released; potential memory leak}} 378} 379 380void mallocMalloc() { 381 int *p = malloc(12); 382 p = malloc(12); // expected-warning{{Memory is 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 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 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 memory after it is freed}} 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 memory after it is freed}} 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 {{Memory is 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 {{Memory is 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 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 488char *ArrayG[12]; 489 490void globalArrayTest() { 491 char *p = (char*)malloc(12); 492 ArrayG[0] = p; 493} 494 495// Make sure that we properly handle a pointer stored into a local struct/array. 496typedef struct _StructWithPtr { 497 int *memP; 498} StructWithPtr; 499 500static StructWithPtr arrOfStructs[10]; 501 502void testMalloc() { 503 int *x = malloc(12); 504 StructWithPtr St; 505 St.memP = x; 506 arrOfStructs[0] = St; 507} 508 509StructWithPtr testMalloc2() { 510 int *x = malloc(12); 511 StructWithPtr St; 512 St.memP = x; 513 return St; 514} 515 516int *testMalloc3() { 517 int *x = malloc(12); 518 int *y = x; 519 return y; 520} 521 522void testElemRegion1() { 523 char *x = (void*)malloc(2); 524 int *ix = (int*)x; 525 free(&(x[0])); 526} 527 528void testElemRegion2(int **pp) { 529 int *p = malloc(12); 530 *pp = p; 531 free(pp[0]); 532} 533 534void testElemRegion3(int **pp) { 535 int *p = malloc(12); 536 *pp = p; 537 free(*pp); 538} 539// Region escape testing. 540 541unsigned takePtrToPtr(int **p); 542void PassTheAddrOfAllocatedData(int f) { 543 int *p = malloc(12); 544 // We don't know what happens after the call. Should stop tracking here. 545 if (takePtrToPtr(&p)) 546 f++; 547 free(p); // no warning 548} 549 550struct X { 551 int *p; 552}; 553unsigned takePtrToStruct(struct X *s); 554int ** foo2(int *g, int f) { 555 int *p = malloc(12); 556 struct X *px= malloc(sizeof(struct X)); 557 px->p = p; 558 // We don't know what happens after this call. Should not track px nor p. 559 if (takePtrToStruct(px)) 560 f++; 561 free(p); 562 return 0; 563} 564 565struct X* RegInvalidationDetect1(struct X *s2) { 566 struct X *px= malloc(sizeof(struct X)); 567 px->p = 0; 568 px = s2; 569 return px; // expected-warning {{Memory is never released; potential memory leak}} 570} 571 572struct X* RegInvalidationGiveUp1() { 573 int *p = malloc(12); 574 struct X *px= malloc(sizeof(struct X)); 575 px->p = p; 576 return px; 577} 578 579int **RegInvalidationDetect2(int **pp) { 580 int *p = malloc(12); 581 pp = &p; 582 pp++; 583 return 0;// expected-warning {{Memory is never released; potential memory leak}} 584} 585 586extern void exit(int) __attribute__ ((__noreturn__)); 587void mallocExit(int *g) { 588 struct xx *p = malloc(12); 589 if (g != 0) 590 exit(1); 591 free(p); 592 return; 593} 594 595extern void __assert_fail (__const char *__assertion, __const char *__file, 596 unsigned int __line, __const char *__function) 597 __attribute__ ((__noreturn__)); 598#define assert(expr) \ 599 ((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__)) 600void mallocAssert(int *g) { 601 struct xx *p = malloc(12); 602 603 assert(g != 0); 604 free(p); 605 return; 606} 607 608void doNotInvalidateWhenPassedToSystemCalls(char *s) { 609 char *p = malloc(12); 610 strlen(p); 611 strcpy(p, s); // expected-warning {{leak}} 612} 613 614// Rely on the CString checker evaluation of the strcpy API to convey that the result of strcpy is equal to p. 615void symbolLostWithStrcpy(char *s) { 616 char *p = malloc(12); 617 p = strcpy(p, s); 618 free(p); 619} 620 621 622// The same test as the one above, but with what is actually generated on a mac. 623static __inline char * 624__inline_strcpy_chk (char *restrict __dest, const char *restrict __src) 625{ 626 return __builtin___strcpy_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1)); 627} 628 629void symbolLostWithStrcpy_InlineStrcpyVersion(char *s) { 630 char *p = malloc(12); 631 p = ((__builtin_object_size (p, 0) != (size_t) -1) ? __builtin___strcpy_chk (p, s, __builtin_object_size (p, 2 > 1)) : __inline_strcpy_chk (p, s)); 632 free(p); 633} 634// Below are the known false positives. 635 636// TODO: There should be no warning here. This one might be difficult to get rid of. 637void dependsOnValueOfPtr(int *g, unsigned f) { 638 int *p; 639 640 if (f) { 641 p = g; 642 } else { 643 p = malloc(12); 644 } 645 646 if (p != g) 647 free(p); 648 else 649 return; // expected-warning{{Memory is never released; potential memory leak}} 650 return; 651} 652 653// TODO: Should this be a warning? 654// Here we are returning a pointer one past the allocated value. An idiom which 655// can be used for implementing special malloc. The correct uses of this might 656// be rare enough so that we could keep this as a warning. 657static void *specialMalloc(int n){ 658 int *p; 659 p = malloc( n+8 ); 660 if( p ){ 661 p[0] = n; 662 p++; 663 } 664 return p;// expected-warning {{Memory is never released; potential memory leak}} 665} 666 667// False negatives. 668 669// TODO: This requires tracking symbols stored inside the structs/arrays. 670void testMalloc5() { 671 StructWithPtr St; 672 StructWithPtr *pSt = &St; 673 pSt->memP = malloc(12); 674} 675 676// TODO: This should produce a warning, similar to the previous issue. 677void localArrayTest() { 678 char *p = (char*)malloc(12); 679 char *ArrayL[12]; 680 ArrayL[0] = p; 681} 682 683