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