brintos

brintos / llvm-project-archived public Read only

0
0
Text · 43.0 KiB · 92b47bc Raw
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