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