1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,alpha.unix.MallocWithAnnotations -analyzer-store=region -verify %s
2*f4a2713aSLionel Sambuc typedef __typeof(sizeof(int)) size_t;
3*f4a2713aSLionel Sambuc void *malloc(size_t);
4*f4a2713aSLionel Sambuc void free(void *);
5*f4a2713aSLionel Sambuc void *realloc(void *ptr, size_t size);
6*f4a2713aSLionel Sambuc void *calloc(size_t nmemb, size_t size);
7*f4a2713aSLionel Sambuc void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
8*f4a2713aSLionel Sambuc void __attribute((ownership_takes(malloc, 1))) my_free(void *);
9*f4a2713aSLionel Sambuc void my_freeBoth(void *, void *)
10*f4a2713aSLionel Sambuc __attribute((ownership_holds(malloc, 1, 2)));
11*f4a2713aSLionel Sambuc void __attribute((ownership_returns(malloc, 1))) *my_malloc2(size_t);
12*f4a2713aSLionel Sambuc void __attribute((ownership_holds(malloc, 1))) my_hold(void *);
13*f4a2713aSLionel Sambuc
14*f4a2713aSLionel Sambuc // Duplicate attributes are silly, but not an error.
15*f4a2713aSLionel Sambuc // Duplicate attribute has no extra effect.
16*f4a2713aSLionel Sambuc // If two are of different kinds, that is an error and reported as such.
17*f4a2713aSLionel Sambuc void __attribute((ownership_holds(malloc, 1)))
18*f4a2713aSLionel Sambuc __attribute((ownership_holds(malloc, 1)))
19*f4a2713aSLionel Sambuc __attribute((ownership_holds(malloc, 3))) my_hold2(void *, void *, void *);
20*f4a2713aSLionel Sambuc void *my_malloc3(size_t);
21*f4a2713aSLionel Sambuc void *myglobalpointer;
22*f4a2713aSLionel Sambuc struct stuff {
23*f4a2713aSLionel Sambuc void *somefield;
24*f4a2713aSLionel Sambuc };
25*f4a2713aSLionel Sambuc struct stuff myglobalstuff;
26*f4a2713aSLionel Sambuc
f1()27*f4a2713aSLionel Sambuc void f1() {
28*f4a2713aSLionel Sambuc int *p = malloc(12);
29*f4a2713aSLionel Sambuc return; // expected-warning{{Potential leak of memory pointed to by}}
30*f4a2713aSLionel Sambuc }
31*f4a2713aSLionel Sambuc
f2()32*f4a2713aSLionel Sambuc void f2() {
33*f4a2713aSLionel Sambuc int *p = malloc(12);
34*f4a2713aSLionel Sambuc free(p);
35*f4a2713aSLionel Sambuc free(p); // expected-warning{{Attempt to free released memory}}
36*f4a2713aSLionel Sambuc }
37*f4a2713aSLionel Sambuc
f2_realloc_0()38*f4a2713aSLionel Sambuc void f2_realloc_0() {
39*f4a2713aSLionel Sambuc int *p = malloc(12);
40*f4a2713aSLionel Sambuc realloc(p,0);
41*f4a2713aSLionel Sambuc realloc(p,0); // expected-warning{{Attempt to free released memory}}
42*f4a2713aSLionel Sambuc }
43*f4a2713aSLionel Sambuc
f2_realloc_1()44*f4a2713aSLionel Sambuc void f2_realloc_1() {
45*f4a2713aSLionel Sambuc int *p = malloc(12);
46*f4a2713aSLionel Sambuc int *q = realloc(p,0); // no-warning
47*f4a2713aSLionel Sambuc }
48*f4a2713aSLionel Sambuc
49*f4a2713aSLionel Sambuc // ownership attributes tests
naf1()50*f4a2713aSLionel Sambuc void naf1() {
51*f4a2713aSLionel Sambuc int *p = my_malloc3(12);
52*f4a2713aSLionel Sambuc return; // no-warning
53*f4a2713aSLionel Sambuc }
54*f4a2713aSLionel Sambuc
n2af1()55*f4a2713aSLionel Sambuc void n2af1() {
56*f4a2713aSLionel Sambuc int *p = my_malloc2(12);
57*f4a2713aSLionel Sambuc return; // expected-warning{{Potential leak of memory pointed to by}}
58*f4a2713aSLionel Sambuc }
59*f4a2713aSLionel Sambuc
af1()60*f4a2713aSLionel Sambuc void af1() {
61*f4a2713aSLionel Sambuc int *p = my_malloc(12);
62*f4a2713aSLionel Sambuc return; // expected-warning{{Potential leak of memory pointed to by}}
63*f4a2713aSLionel Sambuc }
64*f4a2713aSLionel Sambuc
af1_b()65*f4a2713aSLionel Sambuc void af1_b() {
66*f4a2713aSLionel Sambuc int *p = my_malloc(12);
67*f4a2713aSLionel Sambuc } // expected-warning{{Potential leak of memory pointed to by}}
68*f4a2713aSLionel Sambuc
af1_c()69*f4a2713aSLionel Sambuc void af1_c() {
70*f4a2713aSLionel Sambuc myglobalpointer = my_malloc(12); // no-warning
71*f4a2713aSLionel Sambuc }
72*f4a2713aSLionel Sambuc
af1_d()73*f4a2713aSLionel Sambuc void af1_d() {
74*f4a2713aSLionel Sambuc struct stuff mystuff;
75*f4a2713aSLionel Sambuc mystuff.somefield = my_malloc(12);
76*f4a2713aSLionel Sambuc } // expected-warning{{Potential leak of memory pointed to by}}
77*f4a2713aSLionel Sambuc
78*f4a2713aSLionel Sambuc // Test that we can pass out allocated memory via pointer-to-pointer.
af1_e(void ** pp)79*f4a2713aSLionel Sambuc void af1_e(void **pp) {
80*f4a2713aSLionel Sambuc *pp = my_malloc(42); // no-warning
81*f4a2713aSLionel Sambuc }
82*f4a2713aSLionel Sambuc
af1_f(struct stuff * somestuff)83*f4a2713aSLionel Sambuc void af1_f(struct stuff *somestuff) {
84*f4a2713aSLionel Sambuc somestuff->somefield = my_malloc(12); // no-warning
85*f4a2713aSLionel Sambuc }
86*f4a2713aSLionel Sambuc
87*f4a2713aSLionel Sambuc // Allocating memory for a field via multiple indirections to our arguments is OK.
af1_g(struct stuff ** pps)88*f4a2713aSLionel Sambuc void af1_g(struct stuff **pps) {
89*f4a2713aSLionel Sambuc *pps = my_malloc(sizeof(struct stuff)); // no-warning
90*f4a2713aSLionel Sambuc (*pps)->somefield = my_malloc(42); // no-warning
91*f4a2713aSLionel Sambuc }
92*f4a2713aSLionel Sambuc
af2()93*f4a2713aSLionel Sambuc void af2() {
94*f4a2713aSLionel Sambuc int *p = my_malloc(12);
95*f4a2713aSLionel Sambuc my_free(p);
96*f4a2713aSLionel Sambuc free(p); // expected-warning{{Attempt to free released memory}}
97*f4a2713aSLionel Sambuc }
98*f4a2713aSLionel Sambuc
af2b()99*f4a2713aSLionel Sambuc void af2b() {
100*f4a2713aSLionel Sambuc int *p = my_malloc(12);
101*f4a2713aSLionel Sambuc free(p);
102*f4a2713aSLionel Sambuc my_free(p); // expected-warning{{Attempt to free released memory}}
103*f4a2713aSLionel Sambuc }
104*f4a2713aSLionel Sambuc
af2c()105*f4a2713aSLionel Sambuc void af2c() {
106*f4a2713aSLionel Sambuc int *p = my_malloc(12);
107*f4a2713aSLionel Sambuc free(p);
108*f4a2713aSLionel Sambuc my_hold(p); // expected-warning{{Attempt to free released memory}}
109*f4a2713aSLionel Sambuc }
110*f4a2713aSLionel Sambuc
af2d()111*f4a2713aSLionel Sambuc void af2d() {
112*f4a2713aSLionel Sambuc int *p = my_malloc(12);
113*f4a2713aSLionel Sambuc free(p);
114*f4a2713aSLionel Sambuc my_hold2(0, 0, p); // expected-warning{{Attempt to free released memory}}
115*f4a2713aSLionel Sambuc }
116*f4a2713aSLionel Sambuc
117*f4a2713aSLionel Sambuc // No leak if malloc returns null.
af2e()118*f4a2713aSLionel Sambuc void af2e() {
119*f4a2713aSLionel Sambuc int *p = my_malloc(12);
120*f4a2713aSLionel Sambuc if (!p)
121*f4a2713aSLionel Sambuc return; // no-warning
122*f4a2713aSLionel Sambuc free(p); // no-warning
123*f4a2713aSLionel Sambuc }
124*f4a2713aSLionel Sambuc
125*f4a2713aSLionel Sambuc // This case inflicts a possible double-free.
af3()126*f4a2713aSLionel Sambuc void af3() {
127*f4a2713aSLionel Sambuc int *p = my_malloc(12);
128*f4a2713aSLionel Sambuc my_hold(p);
129*f4a2713aSLionel Sambuc free(p); // expected-warning{{Attempt to free non-owned memory}}
130*f4a2713aSLionel Sambuc }
131*f4a2713aSLionel Sambuc
af4()132*f4a2713aSLionel Sambuc int * af4() {
133*f4a2713aSLionel Sambuc int *p = my_malloc(12);
134*f4a2713aSLionel Sambuc my_free(p);
135*f4a2713aSLionel Sambuc return p; // expected-warning{{Use of memory after it is freed}}
136*f4a2713aSLionel Sambuc }
137*f4a2713aSLionel Sambuc
138*f4a2713aSLionel Sambuc // This case is (possibly) ok, be conservative
af5()139*f4a2713aSLionel Sambuc int * af5() {
140*f4a2713aSLionel Sambuc int *p = my_malloc(12);
141*f4a2713aSLionel Sambuc my_hold(p);
142*f4a2713aSLionel Sambuc return p; // no-warning
143*f4a2713aSLionel Sambuc }
144*f4a2713aSLionel Sambuc
145*f4a2713aSLionel Sambuc
146*f4a2713aSLionel Sambuc
147*f4a2713aSLionel Sambuc // This case tests that storing malloc'ed memory to a static variable which is
148*f4a2713aSLionel Sambuc // then returned is not leaked. In the absence of known contracts for functions
149*f4a2713aSLionel Sambuc // or inter-procedural analysis, this is a conservative answer.
f3()150*f4a2713aSLionel Sambuc int *f3() {
151*f4a2713aSLionel Sambuc static int *p = 0;
152*f4a2713aSLionel Sambuc p = malloc(12);
153*f4a2713aSLionel Sambuc return p; // no-warning
154*f4a2713aSLionel Sambuc }
155*f4a2713aSLionel Sambuc
156*f4a2713aSLionel Sambuc // This case tests that storing malloc'ed memory to a static global variable
157*f4a2713aSLionel Sambuc // which is then returned is not leaked. In the absence of known contracts for
158*f4a2713aSLionel Sambuc // functions or inter-procedural analysis, this is a conservative answer.
159*f4a2713aSLionel Sambuc static int *p_f4 = 0;
f4()160*f4a2713aSLionel Sambuc int *f4() {
161*f4a2713aSLionel Sambuc p_f4 = malloc(12);
162*f4a2713aSLionel Sambuc return p_f4; // no-warning
163*f4a2713aSLionel Sambuc }
164*f4a2713aSLionel Sambuc
f5()165*f4a2713aSLionel Sambuc int *f5() {
166*f4a2713aSLionel Sambuc int *q = malloc(12);
167*f4a2713aSLionel Sambuc q = realloc(q, 20);
168*f4a2713aSLionel Sambuc return q; // no-warning
169*f4a2713aSLionel Sambuc }
170*f4a2713aSLionel Sambuc
f6()171*f4a2713aSLionel Sambuc void f6() {
172*f4a2713aSLionel Sambuc int *p = malloc(12);
173*f4a2713aSLionel Sambuc if (!p)
174*f4a2713aSLionel Sambuc return; // no-warning
175*f4a2713aSLionel Sambuc else
176*f4a2713aSLionel Sambuc free(p);
177*f4a2713aSLionel Sambuc }
178*f4a2713aSLionel Sambuc
f6_realloc()179*f4a2713aSLionel Sambuc void f6_realloc() {
180*f4a2713aSLionel Sambuc int *p = malloc(12);
181*f4a2713aSLionel Sambuc if (!p)
182*f4a2713aSLionel Sambuc return; // no-warning
183*f4a2713aSLionel Sambuc else
184*f4a2713aSLionel Sambuc realloc(p,0);
185*f4a2713aSLionel Sambuc }
186*f4a2713aSLionel Sambuc
187*f4a2713aSLionel Sambuc
188*f4a2713aSLionel Sambuc char *doit2();
pr6069()189*f4a2713aSLionel Sambuc void pr6069() {
190*f4a2713aSLionel Sambuc char *buf = doit2();
191*f4a2713aSLionel Sambuc free(buf);
192*f4a2713aSLionel Sambuc }
193*f4a2713aSLionel Sambuc
pr6293()194*f4a2713aSLionel Sambuc void pr6293() {
195*f4a2713aSLionel Sambuc free(0);
196*f4a2713aSLionel Sambuc }
197*f4a2713aSLionel Sambuc
f7()198*f4a2713aSLionel Sambuc void f7() {
199*f4a2713aSLionel Sambuc char *x = (char*) malloc(4);
200*f4a2713aSLionel Sambuc free(x);
201*f4a2713aSLionel Sambuc x[0] = 'a'; // expected-warning{{Use of memory after it is freed}}
202*f4a2713aSLionel Sambuc }
203*f4a2713aSLionel Sambuc
f7_realloc()204*f4a2713aSLionel Sambuc void f7_realloc() {
205*f4a2713aSLionel Sambuc char *x = (char*) malloc(4);
206*f4a2713aSLionel Sambuc realloc(x,0);
207*f4a2713aSLionel Sambuc x[0] = 'a'; // expected-warning{{Use of memory after it is freed}}
208*f4a2713aSLionel Sambuc }
209*f4a2713aSLionel Sambuc
PR6123()210*f4a2713aSLionel Sambuc void PR6123() {
211*f4a2713aSLionel Sambuc int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
212*f4a2713aSLionel Sambuc }
213*f4a2713aSLionel Sambuc
PR7217()214*f4a2713aSLionel Sambuc void PR7217() {
215*f4a2713aSLionel Sambuc int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
216*f4a2713aSLionel Sambuc buf[1] = 'c'; // not crash
217*f4a2713aSLionel Sambuc }
218*f4a2713aSLionel Sambuc
mallocCastToVoid()219*f4a2713aSLionel Sambuc void mallocCastToVoid() {
220*f4a2713aSLionel Sambuc void *p = malloc(2);
221*f4a2713aSLionel Sambuc const void *cp = p; // not crash
222*f4a2713aSLionel Sambuc free(p);
223*f4a2713aSLionel Sambuc }
224*f4a2713aSLionel Sambuc
mallocCastToFP()225*f4a2713aSLionel Sambuc void mallocCastToFP() {
226*f4a2713aSLionel Sambuc void *p = malloc(2);
227*f4a2713aSLionel Sambuc void (*fp)() = p; // not crash
228*f4a2713aSLionel Sambuc free(p);
229*f4a2713aSLionel Sambuc }
230*f4a2713aSLionel Sambuc
231*f4a2713aSLionel Sambuc // This tests that malloc() buffers are undefined by default
mallocGarbage()232*f4a2713aSLionel Sambuc char mallocGarbage () {
233*f4a2713aSLionel Sambuc char *buf = malloc(2);
234*f4a2713aSLionel Sambuc char result = buf[1]; // expected-warning{{undefined}}
235*f4a2713aSLionel Sambuc free(buf);
236*f4a2713aSLionel Sambuc return result;
237*f4a2713aSLionel Sambuc }
238*f4a2713aSLionel Sambuc
239*f4a2713aSLionel Sambuc // This tests that calloc() buffers need to be freed
callocNoFree()240*f4a2713aSLionel Sambuc void callocNoFree () {
241*f4a2713aSLionel Sambuc char *buf = calloc(2,2);
242*f4a2713aSLionel Sambuc return; // expected-warning{{Potential leak of memory pointed to by}}
243*f4a2713aSLionel Sambuc }
244*f4a2713aSLionel Sambuc
245*f4a2713aSLionel Sambuc // These test that calloc() buffers are zeroed by default
callocZeroesGood()246*f4a2713aSLionel Sambuc char callocZeroesGood () {
247*f4a2713aSLionel Sambuc char *buf = calloc(2,2);
248*f4a2713aSLionel Sambuc char result = buf[3]; // no-warning
249*f4a2713aSLionel Sambuc if (buf[1] == 0) {
250*f4a2713aSLionel Sambuc free(buf);
251*f4a2713aSLionel Sambuc }
252*f4a2713aSLionel Sambuc return result; // no-warning
253*f4a2713aSLionel Sambuc }
254*f4a2713aSLionel Sambuc
callocZeroesBad()255*f4a2713aSLionel Sambuc char callocZeroesBad () {
256*f4a2713aSLionel Sambuc char *buf = calloc(2,2);
257*f4a2713aSLionel Sambuc char result = buf[3]; // no-warning
258*f4a2713aSLionel Sambuc if (buf[1] != 0) {
259*f4a2713aSLionel Sambuc free(buf); // expected-warning{{never executed}}
260*f4a2713aSLionel Sambuc }
261*f4a2713aSLionel Sambuc return result; // expected-warning{{Potential leak of memory pointed to by}}
262*f4a2713aSLionel Sambuc }
263*f4a2713aSLionel Sambuc
testMultipleFreeAnnotations()264*f4a2713aSLionel Sambuc void testMultipleFreeAnnotations() {
265*f4a2713aSLionel Sambuc int *p = malloc(12);
266*f4a2713aSLionel Sambuc int *q = malloc(12);
267*f4a2713aSLionel Sambuc my_freeBoth(p, q);
268*f4a2713aSLionel Sambuc }
269*f4a2713aSLionel Sambuc
270