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