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