1// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s 2 3#include "Inputs/system-header-simulator.h" 4 5void clang_analyzer_eval(int); 6 7typedef __typeof(sizeof(int)) size_t; 8void *malloc(size_t); 9void *alloca(size_t); 10void *valloc(size_t); 11void free(void *); 12void *realloc(void *ptr, size_t size); 13void *reallocf(void *ptr, size_t size); 14void *calloc(size_t nmemb, size_t size); 15char *strdup(const char *s); 16char *strndup(const char *s, size_t n); 17int memcmp(const void *s1, const void *s2, size_t n); 18 19void myfoo(int *p); 20void myfooint(int p); 21char *fooRetPtr(); 22 23void f1() { 24 int *p = malloc(12); 25 return; // expected-warning{{Potential leak of memory pointed to by 'p'}} 26} 27 28void f2() { 29 int *p = malloc(12); 30 free(p); 31 free(p); // expected-warning{{Attempt to free released memory}} 32} 33 34void f2_realloc_0() { 35 int *p = malloc(12); 36 realloc(p,0); 37 realloc(p,0); // expected-warning{{Attempt to free released memory}} 38} 39 40void f2_realloc_1() { 41 int *p = malloc(12); 42 int *q = realloc(p,0); // no-warning 43} 44 45void reallocNotNullPtr(unsigned sizeIn) { 46 unsigned size = 12; 47 char *p = (char*)malloc(size); 48 if (p) { 49 char *q = (char*)realloc(p, sizeIn); 50 char x = *q; // expected-warning {{Potential leak of memory pointed to by 'q'}} 51 } 52} 53 54void allocaTest() { 55 int *p = alloca(sizeof(int)); 56} // no warn 57 58void allocaBuiltinTest() { 59 int *p = __builtin_alloca(sizeof(int)); 60} // no warn 61 62int *realloctest1() { 63 int *q = malloc(12); 64 q = realloc(q, 20); 65 return q; // no warning - returning the allocated value 66} 67 68// p should be freed if realloc fails. 69void reallocFails() { 70 char *p = malloc(12); 71 char *r = realloc(p, 12+1); 72 if (!r) { 73 free(p); 74 } else { 75 free(r); 76 } 77} 78 79void reallocSizeZero1() { 80 char *p = malloc(12); 81 char *r = realloc(p, 0); 82 if (!r) { 83 free(p); // expected-warning {{Attempt to free released memory}} 84 } else { 85 free(r); 86 } 87} 88 89void reallocSizeZero2() { 90 char *p = malloc(12); 91 char *r = realloc(p, 0); 92 if (!r) { 93 free(p); // expected-warning {{Attempt to free released memory}} 94 } else { 95 free(r); 96 } 97 free(p); // expected-warning {{Attempt to free released memory}} 98} 99 100void reallocSizeZero3() { 101 char *p = malloc(12); 102 char *r = realloc(p, 0); 103 free(r); 104} 105 106void reallocSizeZero4() { 107 char *r = realloc(0, 0); 108 free(r); 109} 110 111void reallocSizeZero5() { 112 char *r = realloc(0, 0); 113} 114 115void reallocPtrZero1() { 116 char *r = realloc(0, 12); 117} // expected-warning {{Potential leak of memory pointed to by 'r'}} 118 119void reallocPtrZero2() { 120 char *r = realloc(0, 12); 121 if (r) 122 free(r); 123} 124 125void reallocPtrZero3() { 126 char *r = realloc(0, 12); 127 free(r); 128} 129 130void reallocRadar6337483_1() { 131 char *buf = malloc(100); 132 buf = (char*)realloc(buf, 0x1000000); 133 if (!buf) { 134 return;// expected-warning {{Potential leak of memory pointed to by}} 135 } 136 free(buf); 137} 138 139void reallocRadar6337483_2() { 140 char *buf = malloc(100); 141 char *buf2 = (char*)realloc(buf, 0x1000000); 142 if (!buf2) { 143 ; 144 } else { 145 free(buf2); 146 } 147} // expected-warning {{Potential leak of memory pointed to by}} 148 149void reallocRadar6337483_3() { 150 char * buf = malloc(100); 151 char * tmp; 152 tmp = (char*)realloc(buf, 0x1000000); 153 if (!tmp) { 154 free(buf); 155 return; 156 } 157 buf = tmp; 158 free(buf); 159} 160 161void reallocRadar6337483_4() { 162 char *buf = malloc(100); 163 char *buf2 = (char*)realloc(buf, 0x1000000); 164 if (!buf2) { 165 return; // expected-warning {{Potential leak of memory pointed to by}} 166 } else { 167 free(buf2); 168 } 169} 170 171int *reallocfTest1() { 172 int *q = malloc(12); 173 q = reallocf(q, 20); 174 return q; // no warning - returning the allocated value 175} 176 177void reallocfRadar6337483_4() { 178 char *buf = malloc(100); 179 char *buf2 = (char*)reallocf(buf, 0x1000000); 180 if (!buf2) { 181 return; // no warning - reallocf frees even on failure 182 } else { 183 free(buf2); 184 } 185} 186 187void reallocfRadar6337483_3() { 188 char * buf = malloc(100); 189 char * tmp; 190 tmp = (char*)reallocf(buf, 0x1000000); 191 if (!tmp) { 192 free(buf); // expected-warning {{Attempt to free released memory}} 193 return; 194 } 195 buf = tmp; 196 free(buf); 197} 198 199void reallocfPtrZero1() { 200 char *r = reallocf(0, 12); 201} // expected-warning {{Potential leak of memory pointed to by}} 202 203//------------------- Check usage of zero-allocated memory --------------------- 204void CheckUseZeroAllocatedNoWarn1() { 205 int *p = malloc(0); 206 free(p); // no warning 207} 208 209void CheckUseZeroAllocatedNoWarn2() { 210 int *p = alloca(0); // no warning 211} 212 213void CheckUseZeroAllocatedNoWarn3() { 214 int *p = malloc(0); 215 int *q = realloc(p, 8); // no warning 216 free(q); 217} 218 219void CheckUseZeroAllocatedNoWarn4() { 220 int *p = realloc(0, 8); 221 *p = 1; // no warning 222 free(p); 223} 224 225void CheckUseZeroAllocated1() { 226 int *p = malloc(0); 227 *p = 1; // expected-warning {{Use of zero-allocated memory}} 228 free(p); 229} 230 231char CheckUseZeroAllocated2() { 232 char *p = alloca(0); 233 return *p; // expected-warning {{Use of zero-allocated memory}} 234} 235 236void UseZeroAllocated(int *p) { 237 if (p) 238 *p = 7; // expected-warning {{Use of zero-allocated memory}} 239} 240void CheckUseZeroAllocated3() { 241 int *p = malloc(0); 242 UseZeroAllocated(p); 243} 244 245void f(char); 246void CheckUseZeroAllocated4() { 247 char *p = valloc(0); 248 f(*p); // expected-warning {{Use of zero-allocated memory}} 249 free(p); 250} 251 252void CheckUseZeroAllocated5() { 253 int *p = calloc(0, 2); 254 *p = 1; // expected-warning {{Use of zero-allocated memory}} 255 free(p); 256} 257 258void CheckUseZeroAllocated6() { 259 int *p = calloc(2, 0); 260 *p = 1; // expected-warning {{Use of zero-allocated memory}} 261 free(p); 262} 263 264void CheckUseZeroAllocated7() { 265 int *p = realloc(0, 0); 266 *p = 1; // expected-warning {{Use of zero-allocated memory}} 267 free(p); 268} 269 270void CheckUseZeroAllocated8() { 271 int *p = malloc(8); 272 int *q = realloc(p, 0); 273 *q = 1; // expected-warning {{Use of zero-allocated memory}} 274 free(q); 275} 276 277void CheckUseZeroAllocated9() { 278 int *p = realloc(0, 0); 279 int *q = realloc(p, 0); 280 *q = 1; // expected-warning {{Use of zero-allocated memory}} 281 free(q); 282} 283 284void CheckUseZeroAllocatedPathNoWarn(_Bool b) { 285 int s = 0; 286 if (b) 287 s= 10; 288 289 char *p = malloc(s); 290 291 if (b) 292 *p = 1; // no warning 293 294 free(p); 295} 296 297void CheckUseZeroAllocatedPathWarn(_Bool b) { 298 int s = 10; 299 if (b) 300 s= 0; 301 302 char *p = malloc(s); 303 304 if (b) 305 *p = 1; // expected-warning {{Use of zero-allocated memory}} 306 307 free(p); 308} 309 310void CheckUseZeroReallocatedPathNoWarn(_Bool b) { 311 int s = 0; 312 if (b) 313 s= 10; 314 315 char *p = malloc(8); 316 char *q = realloc(p, s); 317 318 if (b) 319 *q = 1; // no warning 320 321 free(q); 322} 323 324void CheckUseZeroReallocatedPathWarn(_Bool b) { 325 int s = 10; 326 if (b) 327 s= 0; 328 329 char *p = malloc(8); 330 char *q = realloc(p, s); 331 332 if (b) 333 *q = 1; // expected-warning {{Use of zero-allocated memory}} 334 335 free(q); 336} 337 338// This case tests that storing malloc'ed memory to a static variable which is 339// then returned is not leaked. In the absence of known contracts for functions 340// or inter-procedural analysis, this is a conservative answer. 341int *f3() { 342 static int *p = 0; 343 p = malloc(12); 344 return p; // no-warning 345} 346 347// This case tests that storing malloc'ed memory to a static global variable 348// which is then returned is not leaked. In the absence of known contracts for 349// functions or inter-procedural analysis, this is a conservative answer. 350static int *p_f4 = 0; 351int *f4() { 352 p_f4 = malloc(12); 353 return p_f4; // no-warning 354} 355 356int *f5() { 357 int *q = malloc(12); 358 q = realloc(q, 20); 359 return q; // no-warning 360} 361 362void f6() { 363 int *p = malloc(12); 364 if (!p) 365 return; // no-warning 366 else 367 free(p); 368} 369 370void f6_realloc() { 371 int *p = malloc(12); 372 if (!p) 373 return; // no-warning 374 else 375 realloc(p,0); 376} 377 378 379char *doit2(); 380void pr6069() { 381 char *buf = doit2(); 382 free(buf); 383} 384 385void pr6293() { 386 free(0); 387} 388 389void f7() { 390 char *x = (char*) malloc(4); 391 free(x); 392 x[0] = 'a'; // expected-warning{{Use of memory after it is freed}} 393} 394 395void f8() { 396 char *x = (char*) malloc(4); 397 free(x); 398 char *y = strndup(x, 4); // expected-warning{{Use of memory after it is freed}} 399} 400 401void f7_realloc() { 402 char *x = (char*) malloc(4); 403 realloc(x,0); 404 x[0] = 'a'; // expected-warning{{Use of memory after it is freed}} 405} 406 407void PR6123() { 408 int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} 409} 410 411void PR7217() { 412 int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} 413 buf[1] = 'c'; // not crash 414} 415 416void cast_emtpy_struct() { 417 struct st { 418 }; 419 420 struct st *s = malloc(sizeof(struct st)); // no-warning 421 free(s); 422} 423 424void cast_struct_1() { 425 struct st { 426 int i[100]; 427 char j[]; 428 }; 429 430 struct st *s = malloc(sizeof(struct st)); // no-warning 431 free(s); 432} 433 434void cast_struct_2() { 435 struct st { 436 int i[100]; 437 char j[0]; 438 }; 439 440 struct st *s = malloc(sizeof(struct st)); // no-warning 441 free(s); 442} 443 444void cast_struct_3() { 445 struct st { 446 int i[100]; 447 char j[1]; 448 }; 449 450 struct st *s = malloc(sizeof(struct st)); // no-warning 451 free(s); 452} 453 454void cast_struct_4() { 455 struct st { 456 int i[100]; 457 char j[2]; 458 }; 459 460 struct st *s = malloc(sizeof(struct st)); // no-warning 461 free(s); 462} 463 464void cast_struct_5() { 465 struct st { 466 char i[200]; 467 char j[1]; 468 }; 469 470 struct st *s = malloc(sizeof(struct st) - sizeof(char)); // no-warning 471 free(s); 472} 473 474void cast_struct_warn_1() { 475 struct st { 476 int i[100]; 477 char j[2]; 478 }; 479 480 struct st *s = malloc(sizeof(struct st) + 2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} 481 free(s); 482} 483 484void cast_struct_warn_2() { 485 struct st { 486 int i[100]; 487 char j[2]; 488 }; 489 490 struct st *s = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} 491 free(s); 492} 493 494void cast_struct_flex_array_1() { 495 struct st { 496 int i[100]; 497 char j[]; 498 }; 499 500 struct st *s = malloc(sizeof(struct st) + 3); // no-warning 501 free(s); 502} 503 504void cast_struct_flex_array_2() { 505 struct st { 506 int i[100]; 507 char j[0]; 508 }; 509 510 struct st *s = malloc(sizeof(struct st) + 3); // no-warning 511 free(s); 512} 513 514void cast_struct_flex_array_3() { 515 struct st { 516 int i[100]; 517 char j[1]; 518 }; 519 520 struct st *s = malloc(sizeof(struct st) + 3); // no-warning 521 free(s); 522} 523 524void cast_struct_flex_array_4() { 525 struct foo { 526 char f[32]; 527 }; 528 struct st { 529 char i[100]; 530 struct foo data[]; 531 }; 532 533 struct st *s = malloc(sizeof(struct st) + 3 * sizeof(struct foo)); // no-warning 534 free(s); 535} 536 537void cast_struct_flex_array_5() { 538 struct foo { 539 char f[32]; 540 }; 541 struct st { 542 char i[100]; 543 struct foo data[0]; 544 }; 545 546 struct st *s = malloc(sizeof(struct st) + 3 * sizeof(struct foo)); // no-warning 547 free(s); 548} 549 550void cast_struct_flex_array_6() { 551 struct foo { 552 char f[32]; 553 }; 554 struct st { 555 char i[100]; 556 struct foo data[1]; 557 }; 558 559 struct st *s = malloc(sizeof(struct st) + 3 * sizeof(struct foo)); // no-warning 560 free(s); 561} 562 563void cast_struct_flex_array_warn_1() { 564 struct foo { 565 char f[32]; 566 }; 567 struct st { 568 char i[100]; 569 struct foo data[]; 570 }; 571 572 struct st *s = malloc(3 * sizeof(struct st) + 3 * sizeof(struct foo)); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} 573 free(s); 574} 575 576void cast_struct_flex_array_warn_2() { 577 struct foo { 578 char f[32]; 579 }; 580 struct st { 581 char i[100]; 582 struct foo data[0]; 583 }; 584 585 struct st *s = malloc(3 * sizeof(struct st) + 3 * sizeof(struct foo)); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} 586 free(s); 587} 588 589void cast_struct_flex_array_warn_3() { 590 struct foo { 591 char f[32]; 592 }; 593 struct st { 594 char i[100]; 595 struct foo data[1]; 596 }; 597 598 struct st *s = malloc(3 * sizeof(struct st) + 3 * sizeof(struct foo)); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} 599 free(s); 600} 601 602void cast_struct_flex_array_warn_4() { 603 struct st { 604 int i[100]; 605 int j[]; 606 }; 607 608 struct st *s = malloc(sizeof(struct st) + 3); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} 609 free(s); 610} 611 612void cast_struct_flex_array_warn_5() { 613 struct st { 614 int i[100]; 615 int j[0]; 616 }; 617 618 struct st *s = malloc(sizeof(struct st) + 3); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} 619 free(s); 620} 621 622void cast_struct_flex_array_warn_6() { 623 struct st { 624 int i[100]; 625 int j[1]; 626 }; 627 628 struct st *s = malloc(sizeof(struct st) + 3); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}} 629 free(s); 630} 631 632void mallocCastToVoid() { 633 void *p = malloc(2); 634 const void *cp = p; // not crash 635 free(p); 636} 637 638void mallocCastToFP() { 639 void *p = malloc(2); 640 void (*fp)() = p; // not crash 641 free(p); 642} 643 644// This tests that malloc() buffers are undefined by default 645char mallocGarbage () { 646 char *buf = malloc(2); 647 char result = buf[1]; // expected-warning{{undefined}} 648 free(buf); 649 return result; 650} 651 652// This tests that calloc() buffers need to be freed 653void callocNoFree () { 654 char *buf = calloc(2,2); 655 return; // expected-warning{{Potential leak of memory pointed to by 'buf'}} 656} 657 658// These test that calloc() buffers are zeroed by default 659char callocZeroesGood () { 660 char *buf = calloc(2,2); 661 char result = buf[3]; // no-warning 662 if (buf[1] == 0) { 663 free(buf); 664 } 665 return result; // no-warning 666} 667 668char callocZeroesBad () { 669 char *buf = calloc(2,2); 670 char result = buf[3]; // no-warning 671 if (buf[1] != 0) { 672 free(buf); // expected-warning{{never executed}} 673 } 674 return result; // expected-warning{{Potential leak of memory pointed to by 'buf'}} 675} 676 677void nullFree() { 678 int *p = 0; 679 free(p); // no warning - a nop 680} 681 682void paramFree(int *p) { 683 myfoo(p); 684 free(p); // no warning 685 myfoo(p); // expected-warning {{Use of memory after it is freed}} 686} 687 688int* mallocEscapeRet() { 689 int *p = malloc(12); 690 return p; // no warning 691} 692 693void mallocEscapeFoo() { 694 int *p = malloc(12); 695 myfoo(p); 696 return; // no warning 697} 698 699void mallocEscapeFree() { 700 int *p = malloc(12); 701 myfoo(p); 702 free(p); 703} 704 705void mallocEscapeFreeFree() { 706 int *p = malloc(12); 707 myfoo(p); 708 free(p); 709 free(p); // expected-warning{{Attempt to free released memory}} 710} 711 712void mallocEscapeFreeUse() { 713 int *p = malloc(12); 714 myfoo(p); 715 free(p); 716 myfoo(p); // expected-warning{{Use of memory after it is freed}} 717} 718 719int *myalloc(); 720void myalloc2(int **p); 721 722void mallocEscapeFreeCustomAlloc() { 723 int *p = malloc(12); 724 myfoo(p); 725 free(p); 726 p = myalloc(); 727 free(p); // no warning 728} 729 730void mallocEscapeFreeCustomAlloc2() { 731 int *p = malloc(12); 732 myfoo(p); 733 free(p); 734 myalloc2(&p); 735 free(p); // no warning 736} 737 738void mallocBindFreeUse() { 739 int *x = malloc(12); 740 int *y = x; 741 free(y); 742 myfoo(x); // expected-warning{{Use of memory after it is freed}} 743} 744 745void mallocEscapeMalloc() { 746 int *p = malloc(12); 747 myfoo(p); 748 p = malloc(12); 749} // expected-warning{{Potential leak of memory pointed to by}} 750 751void mallocMalloc() { 752 int *p = malloc(12); 753 p = malloc(12); 754} // expected-warning {{Potential leak of memory pointed to by}} 755 756void mallocFreeMalloc() { 757 int *p = malloc(12); 758 free(p); 759 p = malloc(12); 760 free(p); 761} 762 763void mallocFreeUse_params() { 764 int *p = malloc(12); 765 free(p); 766 myfoo(p); //expected-warning{{Use of memory after it is freed}} 767} 768 769void mallocFreeUse_params2() { 770 int *p = malloc(12); 771 free(p); 772 myfooint(*p); //expected-warning{{Use of memory after it is freed}} 773} 774 775void mallocFailedOrNot() { 776 int *p = malloc(12); 777 if (!p) 778 free(p); 779 else 780 free(p); 781} 782 783struct StructWithInt { 784 int g; 785}; 786 787int *mallocReturnFreed() { 788 int *p = malloc(12); 789 free(p); 790 return p; // expected-warning {{Use of memory after it is freed}} 791} 792 793int useAfterFreeStruct() { 794 struct StructWithInt *px= malloc(sizeof(struct StructWithInt)); 795 px->g = 5; 796 free(px); 797 return px->g; // expected-warning {{Use of memory after it is freed}} 798} 799 800void nonSymbolAsFirstArg(int *pp, struct StructWithInt *p); 801 802void mallocEscapeFooNonSymbolArg() { 803 struct StructWithInt *p = malloc(sizeof(struct StructWithInt)); 804 nonSymbolAsFirstArg(&p->g, p); 805 return; // no warning 806} 807 808void mallocFailedOrNotLeak() { 809 int *p = malloc(12); 810 if (p == 0) 811 return; // no warning 812 else 813 return; // expected-warning {{Potential leak of memory pointed to by}} 814} 815 816void mallocAssignment() { 817 char *p = malloc(12); 818 p = fooRetPtr(); 819} // expected-warning {{leak}} 820 821int vallocTest() { 822 char *mem = valloc(12); 823 return 0; // expected-warning {{Potential leak of memory pointed to by}} 824} 825 826void vallocEscapeFreeUse() { 827 int *p = valloc(12); 828 myfoo(p); 829 free(p); 830 myfoo(p); // expected-warning{{Use of memory after it is freed}} 831} 832 833int *Gl; 834struct GlStTy { 835 int *x; 836}; 837 838struct GlStTy GlS = {0}; 839 840void GlobalFree() { 841 free(Gl); 842} 843 844void GlobalMalloc() { 845 Gl = malloc(12); 846} 847 848void GlobalStructMalloc() { 849 int *a = malloc(12); 850 GlS.x = a; 851} 852 853void GlobalStructMallocFree() { 854 int *a = malloc(12); 855 GlS.x = a; 856 free(GlS.x); 857} 858 859char *ArrayG[12]; 860 861void globalArrayTest() { 862 char *p = (char*)malloc(12); 863 ArrayG[0] = p; 864} 865 866// Make sure that we properly handle a pointer stored into a local struct/array. 867typedef struct _StructWithPtr { 868 int *memP; 869} StructWithPtr; 870 871static StructWithPtr arrOfStructs[10]; 872 873void testMalloc() { 874 int *x = malloc(12); 875 StructWithPtr St; 876 St.memP = x; 877 arrOfStructs[0] = St; // no-warning 878} 879 880StructWithPtr testMalloc2() { 881 int *x = malloc(12); 882 StructWithPtr St; 883 St.memP = x; 884 return St; // no-warning 885} 886 887int *testMalloc3() { 888 int *x = malloc(12); 889 int *y = x; 890 return y; // no-warning 891} 892 893void testStructLeak() { 894 StructWithPtr St; 895 St.memP = malloc(12); 896 return; // expected-warning {{Potential leak of memory pointed to by 'St.memP'}} 897} 898 899void testElemRegion1() { 900 char *x = (void*)malloc(2); 901 int *ix = (int*)x; 902 free(&(x[0])); 903} 904 905void testElemRegion2(int **pp) { 906 int *p = malloc(12); 907 *pp = p; 908 free(pp[0]); 909} 910 911void testElemRegion3(int **pp) { 912 int *p = malloc(12); 913 *pp = p; 914 free(*pp); 915} 916// Region escape testing. 917 918unsigned takePtrToPtr(int **p); 919void PassTheAddrOfAllocatedData(int f) { 920 int *p = malloc(12); 921 // We don't know what happens after the call. Should stop tracking here. 922 if (takePtrToPtr(&p)) 923 f++; 924 free(p); // no warning 925} 926 927struct X { 928 int *p; 929}; 930unsigned takePtrToStruct(struct X *s); 931int ** foo2(int *g, int f) { 932 int *p = malloc(12); 933 struct X *px= malloc(sizeof(struct X)); 934 px->p = p; 935 // We don't know what happens after this call. Should not track px nor p. 936 if (takePtrToStruct(px)) 937 f++; 938 free(p); 939 return 0; 940} 941 942struct X* RegInvalidationDetect1(struct X *s2) { 943 struct X *px= malloc(sizeof(struct X)); 944 px->p = 0; 945 px = s2; 946 return px; // expected-warning {{Potential leak of memory pointed to by}} 947} 948 949struct X* RegInvalidationGiveUp1() { 950 int *p = malloc(12); 951 struct X *px= malloc(sizeof(struct X)); 952 px->p = p; 953 return px; 954} 955 956int **RegInvalidationDetect2(int **pp) { 957 int *p = malloc(12); 958 pp = &p; 959 pp++; 960 return 0;// expected-warning {{Potential leak of memory pointed to by}} 961} 962 963extern void exit(int) __attribute__ ((__noreturn__)); 964void mallocExit(int *g) { 965 struct xx *p = malloc(12); 966 if (g != 0) 967 exit(1); 968 free(p); 969 return; 970} 971 972extern void __assert_fail (__const char *__assertion, __const char *__file, 973 unsigned int __line, __const char *__function) 974 __attribute__ ((__noreturn__)); 975#define assert(expr) \ 976 ((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__)) 977void mallocAssert(int *g) { 978 struct xx *p = malloc(12); 979 980 assert(g != 0); 981 free(p); 982 return; 983} 984 985void doNotInvalidateWhenPassedToSystemCalls(char *s) { 986 char *p = malloc(12); 987 strlen(p); 988 strcpy(p, s); 989 strcpy(s, p); 990 strcpy(p, p); 991 memcpy(p, s, 1); 992 memcpy(s, p, 1); 993 memcpy(p, p, 1); 994} // expected-warning {{leak}} 995 996// Treat source buffer contents as escaped. 997void escapeSourceContents(char *s) { 998 char *p = malloc(12); 999 memcpy(s, &p, 12); // no warning 1000 1001 void *p1 = malloc(7); 1002 char *a; 1003 memcpy(&a, &p1, sizeof a); 1004 // FIXME: No warning due to limitations imposed by current modelling of 1005 // 'memcpy' (regions metadata is not copied). 1006 1007 int *ptrs[2]; 1008 int *allocated = (int *)malloc(4); 1009 memcpy(&ptrs[0], &allocated, sizeof(int *)); 1010 // FIXME: No warning due to limitations imposed by current modelling of 1011 // 'memcpy' (regions metadata is not copied). 1012} 1013 1014void invalidateDestinationContents() { 1015 int *null = 0; 1016 int *p = (int *)malloc(4); 1017 memcpy(&p, &null, sizeof(int *)); 1018 1019 int *ptrs1[2]; // expected-warning {{Potential leak of memory pointed to by}} 1020 ptrs1[0] = (int *)malloc(4); 1021 memcpy(ptrs1, &null, sizeof(int *)); 1022 1023 int *ptrs2[2]; // expected-warning {{Potential memory leak}} 1024 ptrs2[0] = (int *)malloc(4); 1025 memcpy(&ptrs2[1], &null, sizeof(int *)); 1026 1027 int *ptrs3[2]; // expected-warning {{Potential memory leak}} 1028 ptrs3[0] = (int *)malloc(4); 1029 memcpy(&ptrs3[0], &null, sizeof(int *)); 1030} // expected-warning {{Potential memory leak}} 1031 1032// Rely on the CString checker evaluation of the strcpy API to convey that the result of strcpy is equal to p. 1033void symbolLostWithStrcpy(char *s) { 1034 char *p = malloc(12); 1035 p = strcpy(p, s); 1036 free(p); 1037} 1038 1039 1040// The same test as the one above, but with what is actually generated on a mac. 1041static __inline char * 1042__inline_strcpy_chk (char *restrict __dest, const char *restrict __src) 1043{ 1044 return __builtin___strcpy_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1)); 1045} 1046 1047void symbolLostWithStrcpy_InlineStrcpyVersion(char *s) { 1048 char *p = malloc(12); 1049 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)); 1050 free(p); 1051} 1052 1053// Here we are returning a pointer one past the allocated value. An idiom which 1054// can be used for implementing special malloc. The correct uses of this might 1055// be rare enough so that we could keep this as a warning. 1056static void *specialMalloc(int n){ 1057 int *p; 1058 p = malloc( n+8 ); 1059 if( p ){ 1060 p[0] = n; 1061 p++; 1062 } 1063 return p; 1064} 1065 1066// Potentially, the user could free the struct by performing pointer arithmetic on the return value. 1067// This is a variation of the specialMalloc issue, though probably would be more rare in correct code. 1068int *specialMallocWithStruct() { 1069 struct StructWithInt *px= malloc(sizeof(struct StructWithInt)); 1070 return &(px->g); 1071} 1072 1073// Test various allocation/deallocation functions. 1074void testStrdup(const char *s, unsigned validIndex) { 1075 char *s2 = strdup(s); 1076 s2[validIndex + 1] = 'b'; 1077} // expected-warning {{Potential leak of memory pointed to by}} 1078 1079int testStrndup(const char *s, unsigned validIndex, unsigned size) { 1080 char *s2 = strndup(s, size); 1081 s2 [validIndex + 1] = 'b'; 1082 if (s2[validIndex] != 'a') 1083 return 0; 1084 else 1085 return 1;// expected-warning {{Potential leak of memory pointed to by}} 1086} 1087 1088void testStrdupContentIsDefined(const char *s, unsigned validIndex) { 1089 char *s2 = strdup(s); 1090 char result = s2[1];// no warning 1091 free(s2); 1092} 1093 1094// ---------------------------------------------------------------------------- 1095// Test the system library functions to which the pointer can escape. 1096// This tests false positive suppression. 1097 1098// For now, we assume memory passed to pthread_specific escapes. 1099// TODO: We could check that if a new pthread binding is set, the existing 1100// binding must be freed; otherwise, a memory leak can occur. 1101void testPthereadSpecificEscape(pthread_key_t key) { 1102 void *buf = malloc(12); 1103 pthread_setspecific(key, buf); // no warning 1104} 1105 1106// PR12101: Test funopen(). 1107static int releasePtr(void *_ctx) { 1108 free(_ctx); 1109 return 0; 1110} 1111FILE *useFunOpen() { 1112 void *ctx = malloc(sizeof(int)); 1113 FILE *f = funopen(ctx, 0, 0, 0, releasePtr); // no warning 1114 if (f == 0) { 1115 free(ctx); 1116 } 1117 return f; 1118} 1119FILE *useFunOpenNoReleaseFunction() { 1120 void *ctx = malloc(sizeof(int)); 1121 FILE *f = funopen(ctx, 0, 0, 0, 0); 1122 if (f == 0) { 1123 free(ctx); 1124 } 1125 return f; // expected-warning{{leak}} 1126} 1127 1128static int readNothing(void *_ctx, char *buf, int size) { 1129 return 0; 1130} 1131FILE *useFunOpenReadNoRelease() { 1132 void *ctx = malloc(sizeof(int)); 1133 FILE *f = funopen(ctx, readNothing, 0, 0, 0); 1134 if (f == 0) { 1135 free(ctx); 1136 } 1137 return f; // expected-warning{{leak}} 1138} 1139 1140// Test setbuf, setvbuf. 1141int my_main_no_warning() { 1142 char *p = malloc(100); 1143 setvbuf(stdout, p, 0, 100); 1144 return 0; 1145} 1146int my_main_no_warning2() { 1147 char *p = malloc(100); 1148 setbuf(__stdoutp, p); 1149 return 0; 1150} 1151int my_main_warn(FILE *f) { 1152 char *p = malloc(100); 1153 setvbuf(f, p, 0, 100); 1154 return 0;// expected-warning {{leak}} 1155} 1156 1157// <rdar://problem/10978247>. 1158// some people use stack allocated memory as an optimization to avoid 1159// a heap allocation for small work sizes. This tests the analyzer's 1160// understanding that the malloc'ed memory is not the same as stackBuffer. 1161void radar10978247(int myValueSize) { 1162 char stackBuffer[128]; 1163 char *buffer; 1164 1165 if (myValueSize <= sizeof(stackBuffer)) 1166 buffer = stackBuffer; 1167 else 1168 buffer = malloc(myValueSize); 1169 1170 // do stuff with the buffer 1171 if (buffer != stackBuffer) 1172 free(buffer); 1173} 1174 1175void radar10978247_positive(int myValueSize) { 1176 char stackBuffer[128]; 1177 char *buffer; 1178 1179 if (myValueSize <= sizeof(stackBuffer)) 1180 buffer = stackBuffer; 1181 else 1182 buffer = malloc(myValueSize); 1183 1184 // do stuff with the buffer 1185 if (buffer == stackBuffer) 1186 return; 1187 else 1188 return; // expected-warning {{leak}} 1189} 1190// <rdar://problem/11269741> Previously this triggered a false positive 1191// because malloc() is known to return uninitialized memory and the binding 1192// of 'o' to 'p->n' was not getting propertly handled. Now we report a leak. 1193struct rdar11269741_a_t { 1194 struct rdar11269741_b_t { 1195 int m; 1196 } n; 1197}; 1198 1199int rdar11269741(struct rdar11269741_b_t o) 1200{ 1201 struct rdar11269741_a_t *p = (struct rdar11269741_a_t *) malloc(sizeof(*p)); 1202 p->n = o; 1203 return p->n.m; // expected-warning {{leak}} 1204} 1205 1206// Pointer arithmetic, returning an ElementRegion. 1207void *radar11329382(unsigned bl) { 1208 void *ptr = malloc (16); 1209 ptr = ptr + (2 - bl); 1210 return ptr; // no warning 1211} 1212 1213void __assert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__)); 1214int strcmp(const char *, const char *); 1215char *a (void); 1216void radar11270219(void) { 1217 char *x = a(), *y = a(); 1218 (__builtin_expect(!(x && y), 0) ? __assert_rtn(__func__, "/Users/zaks/tmp/ex.c", 24, "x && y") : (void)0); 1219 strcmp(x, y); // no warning 1220} 1221 1222void radar_11358224_test_double_assign_ints_positive_2() 1223{ 1224 void *ptr = malloc(16); 1225 ptr = ptr; 1226} // expected-warning {{leak}} 1227 1228// Assume that functions which take a function pointer can free memory even if 1229// they are defined in system headers and take the const pointer to the 1230// allocated memory. (radar://11160612) 1231int const_ptr_and_callback(int, const char*, int n, void(*)(void*)); 1232void r11160612_1() { 1233 char *x = malloc(12); 1234 const_ptr_and_callback(0, x, 12, free); // no - warning 1235} 1236 1237// Null is passed as callback. 1238void r11160612_2() { 1239 char *x = malloc(12); 1240 const_ptr_and_callback(0, x, 12, 0); 1241} // expected-warning {{leak}} 1242 1243// Callback is passed to a function defined in a system header. 1244void r11160612_4() { 1245 char *x = malloc(12); 1246 sqlite3_bind_text_my(0, x, 12, free); // no - warning 1247} 1248 1249// Passing callbacks in a struct. 1250void r11160612_5(StWithCallback St) { 1251 void *x = malloc(12); 1252 dealocateMemWhenDoneByVal(x, St); 1253} 1254void r11160612_6(StWithCallback St) { 1255 void *x = malloc(12); 1256 dealocateMemWhenDoneByRef(&St, x); 1257} 1258 1259int mySub(int, int); 1260int myAdd(int, int); 1261int fPtr(unsigned cond, int x) { 1262 return (cond ? mySub : myAdd)(x, x); 1263} 1264 1265// Test anti-aliasing. 1266 1267void dependsOnValueOfPtr(int *g, unsigned f) { 1268 int *p; 1269 1270 if (f) { 1271 p = g; 1272 } else { 1273 p = malloc(12); 1274 } 1275 1276 if (p != g) 1277 free(p); 1278 else 1279 return; // no warning 1280 return; 1281} 1282 1283int CMPRegionHeapToStack() { 1284 int x = 0; 1285 int *x1 = malloc(8); 1286 int *x2 = &x; 1287 clang_analyzer_eval(x1 == x2); // expected-warning{{FALSE}} 1288 free(x1); 1289 return x; 1290} 1291 1292int CMPRegionHeapToHeap2() { 1293 int x = 0; 1294 int *x1 = malloc(8); 1295 int *x2 = malloc(8); 1296 int *x4 = x1; 1297 int *x5 = x2; 1298 clang_analyzer_eval(x4 == x5); // expected-warning{{FALSE}} 1299 free(x1); 1300 free(x2); 1301 return x; 1302} 1303 1304int CMPRegionHeapToHeap() { 1305 int x = 0; 1306 int *x1 = malloc(8); 1307 int *x4 = x1; 1308 if (x1 == x4) { 1309 free(x1); 1310 return 5/x; // expected-warning{{Division by zero}} 1311 } 1312 return x;// expected-warning{{This statement is never executed}} 1313} 1314 1315int HeapAssignment() { 1316 int m = 0; 1317 int *x = malloc(4); 1318 int *y = x; 1319 *x = 5; 1320 clang_analyzer_eval(*x != *y); // expected-warning{{FALSE}} 1321 free(x); 1322 return 0; 1323} 1324 1325int *retPtr(); 1326int *retPtrMightAlias(int *x); 1327int cmpHeapAllocationToUnknown() { 1328 int zero = 0; 1329 int *yBefore = retPtr(); 1330 int *m = malloc(8); 1331 int *yAfter = retPtrMightAlias(m); 1332 clang_analyzer_eval(yBefore == m); // expected-warning{{FALSE}} 1333 clang_analyzer_eval(yAfter == m); // expected-warning{{FALSE}} 1334 free(m); 1335 return 0; 1336} 1337 1338void localArrayTest() { 1339 char *p = (char*)malloc(12); 1340 char *ArrayL[12]; 1341 ArrayL[0] = p; 1342} // expected-warning {{leak}} 1343 1344void localStructTest() { 1345 StructWithPtr St; 1346 StructWithPtr *pSt = &St; 1347 pSt->memP = malloc(12); 1348} // expected-warning{{Potential leak of memory pointed to by}} 1349 1350#ifdef __INTPTR_TYPE__ 1351// Test double assignment through integers. 1352typedef __INTPTR_TYPE__ intptr_t; 1353typedef unsigned __INTPTR_TYPE__ uintptr_t; 1354 1355static intptr_t glob; 1356void test_double_assign_ints() 1357{ 1358 void *ptr = malloc (16); // no-warning 1359 glob = (intptr_t)(uintptr_t)ptr; 1360} 1361 1362void test_double_assign_ints_positive() 1363{ 1364 void *ptr = malloc(16); 1365 (void*)(intptr_t)(uintptr_t)ptr; // expected-warning {{unused}} 1366} // expected-warning {{leak}} 1367#endif 1368 1369void testCGContextNoLeak() 1370{ 1371 void *ptr = malloc(16); 1372 CGContextRef context = CGBitmapContextCreate(ptr); 1373 1374 // Because you can get the data back out like this, even much later, 1375 // CGBitmapContextCreate is one of our "stop-tracking" exceptions. 1376 free(CGBitmapContextGetData(context)); 1377} 1378 1379void testCGContextLeak() 1380{ 1381 void *ptr = malloc(16); 1382 CGContextRef context = CGBitmapContextCreate(ptr); 1383 // However, this time we're just leaking the data, because the context 1384 // object doesn't escape and it hasn't been freed in this function. 1385} 1386 1387// Allow xpc context to escape. radar://11635258 1388// TODO: Would be great if we checked that the finalize_connection_context actually releases it. 1389static void finalize_connection_context(void *ctx) { 1390 int *context = ctx; 1391 free(context); 1392} 1393void foo (xpc_connection_t peer) { 1394 int *ctx = calloc(1, sizeof(int)); 1395 xpc_connection_set_context(peer, ctx); 1396 xpc_connection_set_finalizer_f(peer, finalize_connection_context); 1397 xpc_connection_resume(peer); 1398} 1399 1400// Make sure we catch errors when we free in a function which does not allocate memory. 1401void freeButNoMalloc(int *p, int x){ 1402 if (x) { 1403 free(p); 1404 //user forgot a return here. 1405 } 1406 free(p); // expected-warning {{Attempt to free released memory}} 1407} 1408 1409struct HasPtr { 1410 char *p; 1411}; 1412 1413char* reallocButNoMalloc(struct HasPtr *a, int c, int size) { 1414 int *s; 1415 char *b = realloc(a->p, size); 1416 char *m = realloc(a->p, size); // expected-warning {{Attempt to free released memory}} 1417 // We don't expect a use-after-free for a->P here because the warning above 1418 // is a sink. 1419 return a->p; // no-warning 1420} 1421 1422// We should not warn in this case since the caller will presumably free a->p in all cases. 1423int reallocButNoMallocPR13674(struct HasPtr *a, int c, int size) { 1424 int *s; 1425 char *b = realloc(a->p, size); 1426 if (b == 0) 1427 return -1; 1428 a->p = b; 1429 return 0; 1430} 1431 1432// Test realloc with no visible malloc. 1433void *test(void *ptr) { 1434 void *newPtr = realloc(ptr, 4); 1435 if (newPtr == 0) { 1436 if (ptr) 1437 free(ptr); // no-warning 1438 } 1439 return newPtr; 1440} 1441 1442 1443char *testLeakWithinReturn(char *str) { 1444 return strdup(strdup(str)); // expected-warning{{leak}} 1445} 1446 1447void passConstPtr(const char * ptr); 1448 1449void testPassConstPointer() { 1450 char * string = malloc(sizeof(char)*10); 1451 passConstPtr(string); 1452 return; // expected-warning {{leak}} 1453} 1454 1455void testPassConstPointerIndirectly() { 1456 char *p = malloc(1); 1457 p++; 1458 memcmp(p, p, sizeof(&p)); 1459 return; // expected-warning {{leak}} 1460} 1461 1462void testPassConstPointerIndirectlyStruct() { 1463 struct HasPtr hp; 1464 hp.p = malloc(10); 1465 memcmp(&hp, &hp, sizeof(hp)); 1466 return; // expected-warning {{Potential leak of memory pointed to by 'hp.p'}} 1467} 1468 1469void testPassToSystemHeaderFunctionIndirectlyStruct() { 1470 SomeStruct ss; 1471 ss.p = malloc(1); 1472 fakeSystemHeaderCall(&ss); // invalidates ss, making ss.p unreachable 1473 // Technically a false negative here -- we know the system function won't free 1474 // ss.p, but nothing else will either! 1475} // no-warning 1476 1477void testPassToSystemHeaderFunctionIndirectlyStructFree() { 1478 SomeStruct ss; 1479 ss.p = malloc(1); 1480 fakeSystemHeaderCall(&ss); // invalidates ss, making ss.p unreachable 1481 free(ss.p); 1482} // no-warning 1483 1484void testPassToSystemHeaderFunctionIndirectlyArray() { 1485 int *p[1]; 1486 p[0] = malloc(sizeof(int)); 1487 fakeSystemHeaderCallIntPtr(p); // invalidates p, making p[0] unreachable 1488 // Technically a false negative here -- we know the system function won't free 1489 // p[0], but nothing else will either! 1490} // no-warning 1491 1492void testPassToSystemHeaderFunctionIndirectlyArrayFree() { 1493 int *p[1]; 1494 p[0] = malloc(sizeof(int)); 1495 fakeSystemHeaderCallIntPtr(p); // invalidates p, making p[0] unreachable 1496 free(p[0]); 1497} // no-warning 1498 1499int *testOffsetAllocate(size_t size) { 1500 int *memoryBlock = (int *)malloc(size + sizeof(int)); 1501 return &memoryBlock[1]; // no-warning 1502} 1503 1504void testOffsetDeallocate(int *memoryBlock) { 1505 free(&memoryBlock[-1]); // no-warning 1506} 1507 1508void testOffsetOfRegionFreed() { 1509 __int64_t * array = malloc(sizeof(__int64_t)*2); 1510 array += 1; 1511 free(&array[0]); // expected-warning{{Argument to free() is offset by 8 bytes from the start of memory allocated by malloc()}} 1512} 1513 1514void testOffsetOfRegionFreed2() { 1515 __int64_t *p = malloc(sizeof(__int64_t)*2); 1516 p += 1; 1517 free(p); // expected-warning{{Argument to free() is offset by 8 bytes from the start of memory allocated by malloc()}} 1518} 1519 1520void testOffsetOfRegionFreed3() { 1521 char *r = malloc(sizeof(char)); 1522 r = r - 10; 1523 free(r); // expected-warning {{Argument to free() is offset by -10 bytes from the start of memory allocated by malloc()}} 1524} 1525 1526void testOffsetOfRegionFreedAfterFunctionCall() { 1527 int *p = malloc(sizeof(int)*2); 1528 p += 1; 1529 myfoo(p); 1530 free(p); // expected-warning{{Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()}} 1531} 1532 1533void testFixManipulatedPointerBeforeFree() { 1534 int * array = malloc(sizeof(int)*2); 1535 array += 1; 1536 free(&array[-1]); // no-warning 1537} 1538 1539void testFixManipulatedPointerBeforeFree2() { 1540 char *r = malloc(sizeof(char)); 1541 r = r + 10; 1542 free(r-10); // no-warning 1543} 1544 1545void freeOffsetPointerPassedToFunction() { 1546 __int64_t *p = malloc(sizeof(__int64_t)*2); 1547 p[1] = 0; 1548 p += 1; 1549 myfooint(*p); // not passing the pointer, only a value pointed by pointer 1550 free(p); // expected-warning {{Argument to free() is offset by 8 bytes from the start of memory allocated by malloc()}} 1551} 1552 1553int arbitraryInt(); 1554void freeUnknownOffsetPointer() { 1555 char *r = malloc(sizeof(char)); 1556 r = r + arbitraryInt(); // unable to reason about what the offset might be 1557 free(r); // no-warning 1558} 1559 1560void testFreeNonMallocPointerWithNoOffset() { 1561 char c; 1562 char *r = &c; 1563 r = r + 10; 1564 free(r-10); // expected-warning {{Argument to free() is the address of the local variable 'c', which is not memory allocated by malloc()}} 1565} 1566 1567void testFreeNonMallocPointerWithOffset() { 1568 char c; 1569 char *r = &c; 1570 free(r+1); // expected-warning {{Argument to free() is the address of the local variable 'c', which is not memory allocated by malloc()}} 1571} 1572 1573void testOffsetZeroDoubleFree() { 1574 int *array = malloc(sizeof(int)*2); 1575 int *p = &array[0]; 1576 free(p); 1577 free(&array[0]); // expected-warning{{Attempt to free released memory}} 1578} 1579 1580void testOffsetPassedToStrlen() { 1581 char * string = malloc(sizeof(char)*10); 1582 string += 1; 1583 int length = strlen(string); // expected-warning {{Potential leak of memory pointed to by 'string'}} 1584} 1585 1586void testOffsetPassedToStrlenThenFree() { 1587 char * string = malloc(sizeof(char)*10); 1588 string += 1; 1589 int length = strlen(string); 1590 free(string); // expected-warning {{Argument to free() is offset by 1 byte from the start of memory allocated by malloc()}} 1591} 1592 1593void testOffsetPassedAsConst() { 1594 char * string = malloc(sizeof(char)*10); 1595 string += 1; 1596 passConstPtr(string); 1597 free(string); // expected-warning {{Argument to free() is offset by 1 byte from the start of memory allocated by malloc()}} 1598} 1599 1600char **_vectorSegments; 1601int _nVectorSegments; 1602 1603void poolFreeC(void* s) { 1604 free(s); // no-warning 1605} 1606void freeMemory() { 1607 while (_nVectorSegments) { 1608 poolFreeC(_vectorSegments[_nVectorSegments++]); 1609 } 1610} 1611 1612// PR16730 1613void testReallocEscaped(void **memory) { 1614 *memory = malloc(47); 1615 char *new_memory = realloc(*memory, 47); 1616 if (new_memory != 0) { 1617 *memory = new_memory; 1618 } 1619} 1620 1621// PR16558 1622void *smallocNoWarn(size_t size) { 1623 if (size == 0) { 1624 return malloc(1); // this branch is never called 1625 } 1626 else { 1627 return malloc(size); 1628 } 1629} 1630 1631char *dupstrNoWarn(const char *s) { 1632 const int len = strlen(s); 1633 char *p = (char*) smallocNoWarn(len + 1); 1634 strcpy(p, s); // no-warning 1635 return p; 1636} 1637 1638void *smallocWarn(size_t size) { 1639 if (size == 2) { 1640 return malloc(1); 1641 } 1642 else { 1643 return malloc(size); 1644 } 1645} 1646 1647char *dupstrWarn(const char *s) { 1648 const int len = strlen(s); 1649 char *p = (char*) smallocWarn(len + 1); 1650 strcpy(p, s); // expected-warning{{String copy function overflows destination buffer}} 1651 return p; 1652} 1653 1654int *radar15580979() { 1655 int *data = (int *)malloc(32); 1656 int *p = data ?: (int*)malloc(32); // no warning 1657 return p; 1658} 1659 1660// Some data structures may hold onto the pointer and free it later. 1661void testEscapeThroughSystemCallTakingVoidPointer1(void *queue) { 1662 int *data = (int *)malloc(32); 1663 fake_insque(queue, data); // no warning 1664} 1665 1666void testEscapeThroughSystemCallTakingVoidPointer2(fake_rb_tree_t *rbt) { 1667 int *data = (int *)malloc(32); 1668 fake_rb_tree_init(rbt, data); 1669} //expected-warning{{Potential leak}} 1670 1671void testEscapeThroughSystemCallTakingVoidPointer3(fake_rb_tree_t *rbt) { 1672 int *data = (int *)malloc(32); 1673 fake_rb_tree_init(rbt, data); 1674 fake_rb_tree_insert_node(rbt, data); // no warning 1675} 1676 1677// ---------------------------------------------------------------------------- 1678// False negatives. 1679 1680void testMallocWithParam(int **p) { 1681 *p = (int*) malloc(sizeof(int)); 1682 *p = 0; // FIXME: should warn here 1683} 1684 1685void testMallocWithParam_2(int **p) { 1686 *p = (int*) malloc(sizeof(int)); // no-warning 1687} 1688 1689void testPassToSystemHeaderFunctionIndirectly() { 1690 int *p = malloc(4); 1691 p++; 1692 fakeSystemHeaderCallInt(p); 1693 // FIXME: This is a leak: if we think a system function won't free p, it 1694 // won't free (p-1) either. 1695} 1696