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