xref: /minix3/external/bsd/llvm/dist/clang/test/Analysis/malloc-annotations.c (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
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