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