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