malloc.c revision e17fdb2d5dbf0ffefd417587003eebbe5baf5984
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); 11char *strdup(const char *s); 12char *strndup(const char *s, size_t n); 13 14void myfoo(int *p); 15void myfooint(int p); 16char *fooRetPtr(); 17 18void f1() { 19 int *p = malloc(12); 20 return; // expected-warning{{Memory is never released; potential leak}} 21} 22 23void f2() { 24 int *p = malloc(12); 25 free(p); 26 free(p); // expected-warning{{Attempt to free released memory}} 27} 28 29void f2_realloc_0() { 30 int *p = malloc(12); 31 realloc(p,0); 32 realloc(p,0); // expected-warning{{Attempt to free released memory}} 33} 34 35void f2_realloc_1() { 36 int *p = malloc(12); 37 int *q = realloc(p,0); // no-warning 38} 39 40void reallocNotNullPtr(unsigned sizeIn) { 41 unsigned size = 12; 42 char *p = (char*)malloc(size); 43 if (p) { 44 char *q = (char*)realloc(p, sizeIn); 45 char x = *q; // expected-warning {{Memory is never released; potential leak}} 46 } 47} 48 49int *realloctest1() { 50 int *q = malloc(12); 51 q = realloc(q, 20); 52 return q; // no warning - returning the allocated value 53} 54 55// p should be freed if realloc fails. 56void reallocFails() { 57 char *p = malloc(12); 58 char *r = realloc(p, 12+1); 59 if (!r) { 60 free(p); 61 } else { 62 free(r); 63 } 64} 65 66void reallocSizeZero1() { 67 char *p = malloc(12); 68 char *r = realloc(p, 0); 69 if (!r) { 70 free(p); 71 } else { 72 free(r); 73 } 74} 75 76void reallocSizeZero2() { 77 char *p = malloc(12); 78 char *r = realloc(p, 0); 79 if (!r) { 80 free(p); 81 } else { 82 free(r); 83 } 84 free(p); // expected-warning {{Attempt to free released memory}} 85} 86 87void reallocSizeZero3() { 88 char *p = malloc(12); 89 char *r = realloc(p, 0); 90 free(r); 91} 92 93void reallocSizeZero4() { 94 char *r = realloc(0, 0); 95 free(r); 96} 97 98void reallocSizeZero5() { 99 char *r = realloc(0, 0); 100} 101 102void reallocPtrZero1() { 103 char *r = realloc(0, 12); // expected-warning {{Memory is never released; potential leak}} 104} 105 106void reallocPtrZero2() { 107 char *r = realloc(0, 12); 108 if (r) 109 free(r); 110} 111 112void reallocPtrZero3() { 113 char *r = realloc(0, 12); 114 free(r); 115} 116 117void reallocRadar6337483_1() { 118 char *buf = malloc(100); 119 buf = (char*)realloc(buf, 0x1000000); 120 if (!buf) { 121 return;// expected-warning {{Memory is never released; potential leak}} 122 } 123 free(buf); 124} 125 126void reallocRadar6337483_2() { 127 char *buf = malloc(100); 128 char *buf2 = (char*)realloc(buf, 0x1000000); 129 if (!buf2) { // expected-warning {{Memory is never released; potential leak}} 130 ; 131 } else { 132 free(buf2); 133 } 134} 135 136void reallocRadar6337483_3() { 137 char * buf = malloc(100); 138 char * tmp; 139 tmp = (char*)realloc(buf, 0x1000000); 140 if (!tmp) { 141 free(buf); 142 return; 143 } 144 buf = tmp; 145 free(buf); 146} 147 148void reallocRadar6337483_4() { 149 char *buf = malloc(100); 150 char *buf2 = (char*)realloc(buf, 0x1000000); 151 if (!buf2) { 152 return; // expected-warning {{Memory is never released; potential leak}} 153 } else { 154 free(buf2); 155 } 156} 157 158int *reallocfTest1() { 159 int *q = malloc(12); 160 q = reallocf(q, 20); 161 return q; // no warning - returning the allocated value 162} 163 164void reallocfRadar6337483_4() { 165 char *buf = malloc(100); 166 char *buf2 = (char*)reallocf(buf, 0x1000000); 167 if (!buf2) { 168 return; // no warning - reallocf frees even on failure 169 } else { 170 free(buf2); 171 } 172} 173 174void reallocfRadar6337483_3() { 175 char * buf = malloc(100); 176 char * tmp; 177 tmp = (char*)reallocf(buf, 0x1000000); 178 if (!tmp) { 179 free(buf); // expected-warning {{Attempt to free released memory}} 180 return; 181 } 182 buf = tmp; 183 free(buf); 184} 185 186void reallocfPtrZero1() { 187 char *r = reallocf(0, 12); // expected-warning {{Memory is never released; potential leak}} 188} 189 190 191// This case tests that storing malloc'ed memory to a static variable which is 192// then returned is not leaked. In the absence of known contracts for functions 193// or inter-procedural analysis, this is a conservative answer. 194int *f3() { 195 static int *p = 0; 196 p = malloc(12); 197 return p; // no-warning 198} 199 200// This case tests that storing malloc'ed memory to a static global variable 201// which is then returned is not leaked. In the absence of known contracts for 202// functions or inter-procedural analysis, this is a conservative answer. 203static int *p_f4 = 0; 204int *f4() { 205 p_f4 = malloc(12); 206 return p_f4; // no-warning 207} 208 209int *f5() { 210 int *q = malloc(12); 211 q = realloc(q, 20); 212 return q; // no-warning 213} 214 215void f6() { 216 int *p = malloc(12); 217 if (!p) 218 return; // no-warning 219 else 220 free(p); 221} 222 223void f6_realloc() { 224 int *p = malloc(12); 225 if (!p) 226 return; // no-warning 227 else 228 realloc(p,0); 229} 230 231 232char *doit2(); 233void pr6069() { 234 char *buf = doit2(); 235 free(buf); 236} 237 238void pr6293() { 239 free(0); 240} 241 242void f7() { 243 char *x = (char*) malloc(4); 244 free(x); 245 x[0] = 'a'; // expected-warning{{Use of memory after it is freed}} 246} 247 248void f8() { 249 char *x = (char*) malloc(4); 250 free(x); 251 char *y = strndup(x, 4); // expected-warning{{Use of memory after it is freed}} 252} 253 254void f7_realloc() { 255 char *x = (char*) malloc(4); 256 realloc(x,0); 257 x[0] = 'a'; // expected-warning{{Use of memory after it is freed}} 258} 259 260void PR6123() { 261 int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}} 262} 263 264void PR7217() { 265 int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}} 266 buf[1] = 'c'; // not crash 267} 268 269void mallocCastToVoid() { 270 void *p = malloc(2); 271 const void *cp = p; // not crash 272 free(p); 273} 274 275void mallocCastToFP() { 276 void *p = malloc(2); 277 void (*fp)() = p; // not crash 278 free(p); 279} 280 281// This tests that malloc() buffers are undefined by default 282char mallocGarbage () { 283 char *buf = malloc(2); 284 char result = buf[1]; // expected-warning{{undefined}} 285 free(buf); 286 return result; 287} 288 289// This tests that calloc() buffers need to be freed 290void callocNoFree () { 291 char *buf = calloc(2,2); 292 return; // expected-warning{{never released}} 293} 294 295// These test that calloc() buffers are zeroed by default 296char callocZeroesGood () { 297 char *buf = calloc(2,2); 298 char result = buf[3]; // no-warning 299 if (buf[1] == 0) { 300 free(buf); 301 } 302 return result; // no-warning 303} 304 305char callocZeroesBad () { 306 char *buf = calloc(2,2); 307 char result = buf[3]; // no-warning 308 if (buf[1] != 0) { 309 free(buf); // expected-warning{{never executed}} 310 } 311 return result; // expected-warning{{never released}} 312} 313 314void nullFree() { 315 int *p = 0; 316 free(p); // no warning - a nop 317} 318 319void paramFree(int *p) { 320 myfoo(p); 321 free(p); // no warning 322 myfoo(p); // TODO: This should be a warning. 323} 324 325int* mallocEscapeRet() { 326 int *p = malloc(12); 327 return p; // no warning 328} 329 330void mallocEscapeFoo() { 331 int *p = malloc(12); 332 myfoo(p); 333 return; // no warning 334} 335 336void mallocEscapeFree() { 337 int *p = malloc(12); 338 myfoo(p); 339 free(p); 340} 341 342void mallocEscapeFreeFree() { 343 int *p = malloc(12); 344 myfoo(p); 345 free(p); 346 free(p); // expected-warning{{Attempt to free released memory}} 347} 348 349void mallocEscapeFreeUse() { 350 int *p = malloc(12); 351 myfoo(p); 352 free(p); 353 myfoo(p); // expected-warning{{Use of memory after it is freed}} 354} 355 356int *myalloc(); 357void myalloc2(int **p); 358 359void mallocEscapeFreeCustomAlloc() { 360 int *p = malloc(12); 361 myfoo(p); 362 free(p); 363 p = myalloc(); 364 free(p); // no warning 365} 366 367void mallocEscapeFreeCustomAlloc2() { 368 int *p = malloc(12); 369 myfoo(p); 370 free(p); 371 myalloc2(&p); 372 free(p); // no warning 373} 374 375void mallocBindFreeUse() { 376 int *x = malloc(12); 377 int *y = x; 378 free(y); 379 myfoo(x); // expected-warning{{Use of memory after it is freed}} 380} 381 382void mallocEscapeMalloc() { 383 int *p = malloc(12); 384 myfoo(p); 385 p = malloc(12); // expected-warning{{Memory is never released; potential leak}} 386} 387 388void mallocMalloc() { 389 int *p = malloc(12); 390 p = malloc(12); // expected-warning 2 {{Memory is never released; potential leak}} 391} 392 393void mallocFreeMalloc() { 394 int *p = malloc(12); 395 free(p); 396 p = malloc(12); 397 free(p); 398} 399 400void mallocFreeUse_params() { 401 int *p = malloc(12); 402 free(p); 403 myfoo(p); //expected-warning{{Use of memory after it is freed}} 404} 405 406void mallocFreeUse_params2() { 407 int *p = malloc(12); 408 free(p); 409 myfooint(*p); //expected-warning{{Use of memory after it is freed}} 410} 411 412void mallocFailedOrNot() { 413 int *p = malloc(12); 414 if (!p) 415 free(p); 416 else 417 free(p); 418} 419 420struct StructWithInt { 421 int g; 422}; 423 424int *mallocReturnFreed() { 425 int *p = malloc(12); 426 free(p); 427 return p; // expected-warning {{Use of memory after it is freed}} 428} 429 430int useAfterFreeStruct() { 431 struct StructWithInt *px= malloc(sizeof(struct StructWithInt)); 432 px->g = 5; 433 free(px); 434 return px->g; // expected-warning {{Use of memory after it is freed}} 435} 436 437void nonSymbolAsFirstArg(int *pp, struct StructWithInt *p); 438 439void mallocEscapeFooNonSymbolArg() { 440 struct StructWithInt *p = malloc(sizeof(struct StructWithInt)); 441 nonSymbolAsFirstArg(&p->g, p); 442 return; // no warning 443} 444 445void mallocFailedOrNotLeak() { 446 int *p = malloc(12); 447 if (p == 0) 448 return; // no warning 449 else 450 return; // expected-warning {{Memory is never released; potential leak}} 451} 452 453void mallocAssignment() { 454 char *p = malloc(12); 455 p = fooRetPtr(); // expected-warning {{leak}} 456} 457 458int vallocTest() { 459 char *mem = valloc(12); 460 return 0; // expected-warning {{Memory is never released; potential leak}} 461} 462 463void vallocEscapeFreeUse() { 464 int *p = valloc(12); 465 myfoo(p); 466 free(p); 467 myfoo(p); // expected-warning{{Use of memory after it is freed}} 468} 469 470int *Gl; 471struct GlStTy { 472 int *x; 473}; 474 475struct GlStTy GlS = {0}; 476 477void GlobalFree() { 478 free(Gl); 479} 480 481void GlobalMalloc() { 482 Gl = malloc(12); 483} 484 485void GlobalStructMalloc() { 486 int *a = malloc(12); 487 GlS.x = a; 488} 489 490void GlobalStructMallocFree() { 491 int *a = malloc(12); 492 GlS.x = a; 493 free(GlS.x); 494} 495 496char *ArrayG[12]; 497 498void globalArrayTest() { 499 char *p = (char*)malloc(12); 500 ArrayG[0] = p; 501} 502 503// Make sure that we properly handle a pointer stored into a local struct/array. 504typedef struct _StructWithPtr { 505 int *memP; 506} StructWithPtr; 507 508static StructWithPtr arrOfStructs[10]; 509 510void testMalloc() { 511 int *x = malloc(12); 512 StructWithPtr St; 513 St.memP = x; 514 arrOfStructs[0] = St; 515} 516 517StructWithPtr testMalloc2() { 518 int *x = malloc(12); 519 StructWithPtr St; 520 St.memP = x; 521 return St; 522} 523 524int *testMalloc3() { 525 int *x = malloc(12); 526 int *y = x; 527 return y; 528} 529 530void testElemRegion1() { 531 char *x = (void*)malloc(2); 532 int *ix = (int*)x; 533 free(&(x[0])); 534} 535 536void testElemRegion2(int **pp) { 537 int *p = malloc(12); 538 *pp = p; 539 free(pp[0]); 540} 541 542void testElemRegion3(int **pp) { 543 int *p = malloc(12); 544 *pp = p; 545 free(*pp); 546} 547// Region escape testing. 548 549unsigned takePtrToPtr(int **p); 550void PassTheAddrOfAllocatedData(int f) { 551 int *p = malloc(12); 552 // We don't know what happens after the call. Should stop tracking here. 553 if (takePtrToPtr(&p)) 554 f++; 555 free(p); // no warning 556} 557 558struct X { 559 int *p; 560}; 561unsigned takePtrToStruct(struct X *s); 562int ** foo2(int *g, int f) { 563 int *p = malloc(12); 564 struct X *px= malloc(sizeof(struct X)); 565 px->p = p; 566 // We don't know what happens after this call. Should not track px nor p. 567 if (takePtrToStruct(px)) 568 f++; 569 free(p); 570 return 0; 571} 572 573struct X* RegInvalidationDetect1(struct X *s2) { 574 struct X *px= malloc(sizeof(struct X)); 575 px->p = 0; 576 px = s2; 577 return px; // expected-warning {{Memory is never released; potential leak}} 578} 579 580struct X* RegInvalidationGiveUp1() { 581 int *p = malloc(12); 582 struct X *px= malloc(sizeof(struct X)); 583 px->p = p; 584 return px; 585} 586 587int **RegInvalidationDetect2(int **pp) { 588 int *p = malloc(12); 589 pp = &p; 590 pp++; 591 return 0;// expected-warning {{Memory is never released; potential leak}} 592} 593 594extern void exit(int) __attribute__ ((__noreturn__)); 595void mallocExit(int *g) { 596 struct xx *p = malloc(12); 597 if (g != 0) 598 exit(1); 599 free(p); 600 return; 601} 602 603extern void __assert_fail (__const char *__assertion, __const char *__file, 604 unsigned int __line, __const char *__function) 605 __attribute__ ((__noreturn__)); 606#define assert(expr) \ 607 ((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__)) 608void mallocAssert(int *g) { 609 struct xx *p = malloc(12); 610 611 assert(g != 0); 612 free(p); 613 return; 614} 615 616void doNotInvalidateWhenPassedToSystemCalls(char *s) { 617 char *p = malloc(12); 618 strlen(p); 619 strcpy(p, s); // expected-warning {{leak}} 620} 621 622// Rely on the CString checker evaluation of the strcpy API to convey that the result of strcpy is equal to p. 623void symbolLostWithStrcpy(char *s) { 624 char *p = malloc(12); 625 p = strcpy(p, s); 626 free(p); 627} 628 629 630// The same test as the one above, but with what is actually generated on a mac. 631static __inline char * 632__inline_strcpy_chk (char *restrict __dest, const char *restrict __src) 633{ 634 return __builtin___strcpy_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1)); 635} 636 637void symbolLostWithStrcpy_InlineStrcpyVersion(char *s) { 638 char *p = malloc(12); 639 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)); 640 free(p); 641} 642 643// Here we are returning a pointer one past the allocated value. An idiom which 644// can be used for implementing special malloc. The correct uses of this might 645// be rare enough so that we could keep this as a warning. 646static void *specialMalloc(int n){ 647 int *p; 648 p = malloc( n+8 ); 649 if( p ){ 650 p[0] = n; 651 p++; 652 } 653 return p; 654} 655 656// Potentially, the user could free the struct by performing pointer arithmetic on the return value. 657// This is a variation of the specialMalloc issue, though probably would be more rare in correct code. 658int *specialMallocWithStruct() { 659 struct StructWithInt *px= malloc(sizeof(struct StructWithInt)); 660 return &(px->g); 661} 662 663// Test various allocation/deallocation functions. 664void testStrdup(const char *s, unsigned validIndex) { 665 char *s2 = strdup(s); 666 s2[validIndex + 1] = 'b';// expected-warning {{Memory is never released; potential leak}} 667} 668 669int testStrndup(const char *s, unsigned validIndex, unsigned size) { 670 char *s2 = strndup(s, size); 671 s2 [validIndex + 1] = 'b'; 672 if (s2[validIndex] != 'a') 673 return 0; 674 else 675 return 1;// expected-warning {{Memory is never released; potential leak}} 676} 677 678void testStrdupContentIsDefined(const char *s, unsigned validIndex) { 679 char *s2 = strdup(s); 680 char result = s2[1];// no warning 681 free(s2); 682} 683 684// ---------------------------------------------------------------------------- 685// Test the system library functions to which the pointer can escape. 686// This tests false positive suppression. 687 688// For now, we assume memory passed to pthread_specific escapes. 689// TODO: We could check that if a new pthread binding is set, the existing 690// binding must be freed; otherwise, a memory leak can occur. 691void testPthereadSpecificEscape(pthread_key_t key) { 692 void *buf = malloc(12); 693 pthread_setspecific(key, buf); // no warning 694} 695 696// PR12101: Test funopen(). 697static int releasePtr(void *_ctx) { 698 free(_ctx); 699 return 0; 700} 701FILE *useFunOpen() { 702 void *ctx = malloc(sizeof(int)); 703 FILE *f = funopen(ctx, 0, 0, 0, releasePtr); // no warning 704 if (f == 0) { 705 free(ctx); 706 } 707 return f; 708} 709FILE *useFunOpenNoReleaseFunction() { 710 void *ctx = malloc(sizeof(int)); 711 FILE *f = funopen(ctx, 0, 0, 0, 0); 712 if (f == 0) { 713 free(ctx); 714 } 715 return f; // expected-warning{{leak}} 716} 717 718// Test setbuf, setvbuf. 719int my_main_no_warning() { 720 char *p = malloc(100); 721 setvbuf(stdout, p, 0, 100); 722 return 0; 723} 724int my_main_no_warning2() { 725 char *p = malloc(100); 726 setbuf(__stdoutp, p); 727 return 0; 728} 729int my_main_warn(FILE *f) { 730 char *p = malloc(100); 731 setvbuf(f, p, 0, 100); 732 return 0;// expected-warning {{leak}} 733} 734 735// <rdar://problem/10978247>. 736// some people use stack allocated memory as an optimization to avoid 737// a heap allocation for small work sizes. This tests the analyzer's 738// understanding that the malloc'ed memory is not the same as stackBuffer. 739void radar10978247(int myValueSize) { 740 char stackBuffer[128]; 741 char *buffer; 742 743 if (myValueSize <= sizeof(stackBuffer)) 744 buffer = stackBuffer; 745 else 746 buffer = malloc(myValueSize); 747 748 // do stuff with the buffer 749 if (buffer != stackBuffer) 750 free(buffer); 751} 752 753void radar10978247_positive(int myValueSize) { 754 char stackBuffer[128]; 755 char *buffer; 756 757 if (myValueSize <= sizeof(stackBuffer)) 758 buffer = stackBuffer; 759 else 760 buffer = malloc(myValueSize); 761 762 // do stuff with the buffer 763 if (buffer == stackBuffer) // expected-warning {{leak}} 764 return; 765} 766 767// <rdar://problem/11269741> Previously this triggered a false positive 768// because malloc() is known to return uninitialized memory and the binding 769// of 'o' to 'p->n' was not getting propertly handled. Now we report a leak. 770struct rdar11269741_a_t { 771 struct rdar11269741_b_t { 772 int m; 773 } n; 774}; 775 776int rdar11269741(struct rdar11269741_b_t o) 777{ 778 struct rdar11269741_a_t *p = (struct rdar11269741_a_t *) malloc(sizeof(*p)); 779 p->n = o; 780 return p->n.m; // expected-warning {{leak}} 781} 782 783// Pointer arithmetic, returning an ElementRegion. 784void *radar11329382(unsigned bl) { 785 void *ptr = malloc (16); 786 ptr = ptr + (2 - bl); 787 return ptr; // no warning 788} 789 790void __assert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__)); 791int strcmp(const char *, const char *); 792char *a (void); 793void radar11270219(void) { 794 char *x = a(), *y = a(); 795 (__builtin_expect(!(x && y), 0) ? __assert_rtn(__func__, "/Users/zaks/tmp/ex.c", 24, "x && y") : (void)0); 796 strcmp(x, y); // no warning 797} 798 799void radar_11358224_test_double_assign_ints_positive_2() 800{ 801 void *ptr = malloc(16); 802 ptr = ptr; // expected-warning {{leak}} 803} 804 805// Assume that functions which take a function pointer can free memory even if 806// they are defined in system headers and take the const pointer to the 807// allocated memory. (radar://11160612) 808int const_ptr_and_callback(int, const char*, int n, void(*)(void*)); 809void r11160612_1() { 810 char *x = malloc(12); 811 const_ptr_and_callback(0, x, 12, free); // no - warning 812} 813 814// Null is passed as callback. 815void r11160612_2() { 816 char *x = malloc(12); 817 const_ptr_and_callback(0, x, 12, 0); // expected-warning {{leak}} 818} 819 820// Callback is passed to a function defined in a system header. 821void r11160612_4() { 822 char *x = malloc(12); 823 sqlite3_bind_text_my(0, x, 12, free); // no - warning 824} 825 826// Passing callbacks in a struct. 827void r11160612_5(StWithCallback St) { 828 void *x = malloc(12); 829 dealocateMemWhenDoneByVal(x, St); 830} 831void r11160612_6(StWithCallback St) { 832 void *x = malloc(12); 833 dealocateMemWhenDoneByRef(&St, x); 834} 835 836int mySub(int, int); 837int myAdd(int, int); 838int fPtr(unsigned cond, int x) { 839 return (cond ? mySub : myAdd)(x, x); 840} 841 842// Test anti-aliasing. 843 844void dependsOnValueOfPtr(int *g, unsigned f) { 845 int *p; 846 847 if (f) { 848 p = g; 849 } else { 850 p = malloc(12); 851 } 852 853 if (p != g) 854 free(p); 855 else 856 return; // no warning 857 return; 858} 859 860int CMPRegionHeapToStack() { 861 int x = 0; 862 int *x1 = malloc(8); 863 int *x2 = &x; 864 if (x1 == x2) 865 return 5/x; // expected-warning{{This statement is never executed}} 866 free(x1); 867 return x; 868} 869 870int CMPRegionHeapToHeap2() { 871 int x = 0; 872 int *x1 = malloc(8); 873 int *x2 = malloc(8); 874 int *x4 = x1; 875 int *x5 = x2; 876 if (x4 == x5) 877 return 5/x; // expected-warning{{This statement is never executed}} 878 free(x1); 879 free(x2); 880 return x; 881} 882 883int CMPRegionHeapToHeap() { 884 int x = 0; 885 int *x1 = malloc(8); 886 int *x4 = x1; 887 if (x1 == x4) { 888 free(x1); 889 return 5/x; // expected-warning{{Division by zero}} 890 } 891 return x;// expected-warning{{This statement is never executed}} 892} 893 894int HeapAssignment() { 895 int m = 0; 896 int *x = malloc(4); 897 int *y = x; 898 *x = 5; 899 if (*x != *y) 900 return 5/m; // expected-warning{{This statement is never executed}} 901 free(x); 902 return 0; 903} 904 905// ---------------------------------------------------------------------------- 906// False negatives. 907 908// TODO: This requires tracking symbols stored inside the structs/arrays. 909void testMalloc5() { 910 StructWithPtr St; 911 StructWithPtr *pSt = &St; 912 pSt->memP = malloc(12); 913} 914 915// TODO: This is another false negative. 916void testMallocWithParam(int **p) { 917 *p = (int*) malloc(sizeof(int)); 918 *p = 0; 919} 920 921void testMallocWithParam_2(int **p) { 922 *p = (int*) malloc(sizeof(int)); 923} 924 925// TODO: This should produce a warning, similar to the previous issue. 926void localArrayTest() { 927 char *p = (char*)malloc(12); 928 char *ArrayL[12]; 929 ArrayL[0] = p; 930} 931 932// Test double assignment through integers. 933static long glob; 934void test_double_assign_ints() 935{ 936 void *ptr = malloc (16); // no-warning 937 glob = (long)(unsigned long)ptr; 938} 939 940void test_double_assign_ints_positive() 941{ 942 void *ptr = malloc(16); 943 (void*)(long)(unsigned long)ptr; // expected-warning {{unused}} expected-warning {{leak}} 944} 945 946