malloc.c revision c8bb3befcad8cd8fc9556bc265289b07dc3c94c8
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,experimental.core.CastSize,experimental.unix.Malloc -analyzer-store=region -verify %s
2#include "system-header-simulator.h"
3
4typedef __typeof(sizeof(int)) size_t;
5void *malloc(size_t);
6void free(void *);
7void *realloc(void *ptr, size_t size);
8void *calloc(size_t nmemb, size_t size);
9
10void myfoo(int *p);
11void myfooint(int p);
12
13void f1() {
14  int *p = malloc(12);
15  return; // expected-warning{{Allocated memory never released. Potential memory leak.}}
16}
17
18void f2() {
19  int *p = malloc(12);
20  free(p);
21  free(p); // expected-warning{{Try to free a memory block that has been released}}
22}
23
24void f2_realloc_0() {
25  int *p = malloc(12);
26  realloc(p,0);
27  realloc(p,0); // expected-warning{{Try to free a memory block that has been released}}
28}
29
30void f2_realloc_1() {
31  int *p = malloc(12);
32  int *q = realloc(p,0); // no-warning
33}
34
35void reallocNotNullPtr(unsigned sizeIn) {
36  unsigned size = 12;
37  char *p = (char*)malloc(size);
38  if (p) {
39    char *q = (char*)realloc(p, sizeIn);
40    char x = *q; // expected-warning {{Allocated memory never released.}}
41  }
42}
43
44int *realloctest1() {
45  int *q = malloc(12);
46  q = realloc(q, 20);
47  return q; // no warning - returning the allocated value
48}
49
50// p should be freed if realloc fails.
51void reallocFails() {
52  char *p = malloc(12);
53  char *r = realloc(p, 12+1);
54  if (!r) {
55    free(p);
56  } else {
57    free(r);
58  }
59}
60
61// This case tests that storing malloc'ed memory to a static variable which is
62// then returned is not leaked.  In the absence of known contracts for functions
63// or inter-procedural analysis, this is a conservative answer.
64int *f3() {
65  static int *p = 0;
66  p = malloc(12);
67  return p; // no-warning
68}
69
70// This case tests that storing malloc'ed memory to a static global variable
71// which is then returned is not leaked.  In the absence of known contracts for
72// functions or inter-procedural analysis, this is a conservative answer.
73static int *p_f4 = 0;
74int *f4() {
75  p_f4 = malloc(12);
76  return p_f4; // no-warning
77}
78
79int *f5() {
80  int *q = malloc(12);
81  q = realloc(q, 20);
82  return q; // no-warning
83}
84
85void f6() {
86  int *p = malloc(12);
87  if (!p)
88    return; // no-warning
89  else
90    free(p);
91}
92
93void f6_realloc() {
94  int *p = malloc(12);
95  if (!p)
96    return; // no-warning
97  else
98    realloc(p,0);
99}
100
101
102char *doit2();
103void pr6069() {
104  char *buf = doit2();
105  free(buf);
106}
107
108void pr6293() {
109  free(0);
110}
111
112void f7() {
113  char *x = (char*) malloc(4);
114  free(x);
115  x[0] = 'a'; // expected-warning{{Use of dynamically allocated memory after it is freed.}}
116}
117
118void f7_realloc() {
119  char *x = (char*) malloc(4);
120  realloc(x,0);
121  x[0] = 'a'; // expected-warning{{Use of dynamically allocated memory after it is freed.}}
122}
123
124void PR6123() {
125  int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}}
126}
127
128void PR7217() {
129  int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}}
130  buf[1] = 'c'; // not crash
131}
132
133void mallocCastToVoid() {
134  void *p = malloc(2);
135  const void *cp = p; // not crash
136  free(p);
137}
138
139void mallocCastToFP() {
140  void *p = malloc(2);
141  void (*fp)() = p; // not crash
142  free(p);
143}
144
145// This tests that malloc() buffers are undefined by default
146char mallocGarbage () {
147	char *buf = malloc(2);
148	char result = buf[1]; // expected-warning{{undefined}}
149	free(buf);
150	return result;
151}
152
153// This tests that calloc() buffers need to be freed
154void callocNoFree () {
155  char *buf = calloc(2,2);
156  return; // expected-warning{{never released}}
157}
158
159// These test that calloc() buffers are zeroed by default
160char callocZeroesGood () {
161	char *buf = calloc(2,2);
162	char result = buf[3]; // no-warning
163	if (buf[1] == 0) {
164	  free(buf);
165	}
166	return result; // no-warning
167}
168
169char callocZeroesBad () {
170	char *buf = calloc(2,2);
171	char result = buf[3]; // no-warning
172	if (buf[1] != 0) {
173	  free(buf); // expected-warning{{never executed}}
174	}
175	return result; // expected-warning{{never released}}
176}
177
178void nullFree() {
179  int *p = 0;
180  free(p); // no warning - a nop
181}
182
183void paramFree(int *p) {
184  myfoo(p);
185  free(p); // no warning
186  myfoo(p); // TODO: This should be a warning.
187}
188
189int* mallocEscapeRet() {
190  int *p = malloc(12);
191  return p; // no warning
192}
193
194void mallocEscapeFoo() {
195  int *p = malloc(12);
196  myfoo(p);
197  return; // no warning
198}
199
200void mallocEscapeFree() {
201  int *p = malloc(12);
202  myfoo(p);
203  free(p);
204}
205
206void mallocEscapeFreeFree() {
207  int *p = malloc(12);
208  myfoo(p);
209  free(p);
210  free(p); // expected-warning{{Try to free a memory block that has been released}}
211}
212
213void mallocEscapeFreeUse() {
214  int *p = malloc(12);
215  myfoo(p);
216  free(p);
217  myfoo(p); // expected-warning{{Use of dynamically allocated memory after it is freed.}}
218}
219
220int *myalloc();
221void myalloc2(int **p);
222
223void mallocEscapeFreeCustomAlloc() {
224  int *p = malloc(12);
225  myfoo(p);
226  free(p);
227  p = myalloc();
228  free(p); // no warning
229}
230
231void mallocEscapeFreeCustomAlloc2() {
232  int *p = malloc(12);
233  myfoo(p);
234  free(p);
235  myalloc2(&p);
236  free(p); // no warning
237}
238
239void mallocBindFreeUse() {
240  int *x = malloc(12);
241  int *y = x;
242  free(y);
243  myfoo(x); // expected-warning{{Use of dynamically allocated memory after it is freed.}}
244}
245
246void mallocEscapeMalloc() {
247  int *p = malloc(12);
248  myfoo(p);
249  p = malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak.}}
250}
251
252void mallocMalloc() {
253  int *p = malloc(12);
254  p = malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak}}
255}
256
257void mallocFreeMalloc() {
258  int *p = malloc(12);
259  free(p);
260  p = malloc(12);
261  free(p);
262}
263
264void mallocFreeUse_params() {
265  int *p = malloc(12);
266  free(p);
267  myfoo(p); //expected-warning{{Use of dynamically allocated memory after it is freed}}
268}
269
270void mallocFreeUse_params2() {
271  int *p = malloc(12);
272  free(p);
273  myfooint(*p); //expected-warning{{Use of dynamically allocated memory after it is freed}}
274}
275
276void mallocFailedOrNot() {
277  int *p = malloc(12);
278  if (!p)
279    free(p);
280  else
281    free(p);
282}
283
284struct StructWithInt {
285  int g;
286};
287
288int *mallocReturnFreed() {
289  int *p = malloc(12);
290  free(p);
291  return p; // expected-warning {{Use of dynamically allocated}}
292}
293
294int useAfterFreeStruct() {
295  struct StructWithInt *px= malloc(sizeof(struct StructWithInt));
296  px->g = 5;
297  free(px);
298  return px->g; // expected-warning {{Use of dynamically allocated}}
299}
300
301void nonSymbolAsFirstArg(int *pp, struct StructWithInt *p);
302
303void mallocEscapeFooNonSymbolArg() {
304  struct StructWithInt *p = malloc(sizeof(struct StructWithInt));
305  nonSymbolAsFirstArg(&p->g, p);
306  return; // no warning
307}
308
309void mallocFailedOrNotLeak() {
310  int *p = malloc(12);
311  if (p == 0)
312    return; // no warning
313  else
314    return; // expected-warning {{Allocated memory never released. Potential memory leak.}}
315}
316
317int *Gl;
318struct GlStTy {
319  int *x;
320};
321
322struct GlStTy GlS = {0};
323
324void GlobalFree() {
325  free(Gl);
326}
327
328void GlobalMalloc() {
329  Gl = malloc(12);
330}
331
332void GlobalStructMalloc() {
333  int *a = malloc(12);
334  GlS.x = a;
335}
336
337void GlobalStructMallocFree() {
338  int *a = malloc(12);
339  GlS.x = a;
340  free(GlS.x);
341}
342
343// Region escape testing.
344
345unsigned takePtrToPtr(int **p);
346void PassTheAddrOfAllocatedData(int f) {
347  int *p = malloc(12);
348  // We don't know what happens after the call. Should stop tracking here.
349  if (takePtrToPtr(&p))
350    f++;
351  free(p); // no warning
352}
353
354struct X {
355  int *p;
356};
357unsigned takePtrToStruct(struct X *s);
358int ** foo2(int *g, int f) {
359  int *p = malloc(12);
360  struct X *px= malloc(sizeof(struct X));
361  px->p = p;
362  // We don't know what happens after this call. Should not track px nor p.
363  if (takePtrToStruct(px))
364    f++;
365  free(p);
366  return 0;
367}
368
369struct X* RegInvalidationDetect1(struct X *s2) {
370  struct X *px= malloc(sizeof(struct X));
371  px->p = 0;
372  px = s2;
373  return px; // expected-warning {{Allocated memory never released. Potential memory leak.}}
374}
375
376struct X* RegInvalidationGiveUp1() {
377  int *p = malloc(12);
378  struct X *px= malloc(sizeof(struct X));
379  px->p = p;
380  return px;
381}
382
383int **RegInvalidationDetect2(int **pp) {
384  int *p = malloc(12);
385  pp = &p;
386  pp++;
387  return 0;// expected-warning {{Allocated memory never released. Potential memory leak.}}
388}
389
390extern void exit(int) __attribute__ ((__noreturn__));
391void mallocExit(int *g) {
392  struct xx *p = malloc(12);
393  if (g != 0)
394    exit(1);
395  free(p);
396  return;
397}
398
399extern void __assert_fail (__const char *__assertion, __const char *__file,
400    unsigned int __line, __const char *__function)
401     __attribute__ ((__noreturn__));
402#define assert(expr) \
403  ((expr)  ? (void)(0)  : __assert_fail (#expr, __FILE__, __LINE__, __func__))
404void mallocAssert(int *g) {
405  struct xx *p = malloc(12);
406
407  assert(g != 0);
408  free(p);
409  return;
410}
411
412void doNotInvalidateWhenPassedToSystemCalls(char *s) {
413  char *p = malloc(12);
414  strlen(p);
415  strcpy(p, s); // expected-warning {{leak}}
416}
417
418// Below are the known false positives.
419
420// TODO: There should be no warning here. This one might be difficult to get rid of.
421void dependsOnValueOfPtr(int *g, unsigned f) {
422  int *p;
423
424  if (f) {
425    p = g;
426  } else {
427    p = malloc(12);
428  }
429
430  if (p != g)
431    free(p);
432  else
433    return; // expected-warning{{Allocated memory never released. Potential memory leak}}
434  return;
435}
436
437// TODO: Should this be a warning?
438// Here we are returning a pointer one past the allocated value. An idiom which
439// can be used for implementing special malloc. The correct uses of this might
440// be rare enough so that we could keep this as a warning.
441static void *specialMalloc(int n){
442  int *p;
443  p = malloc( n+8 );
444  if( p ){
445    p[0] = n;
446    p++;
447  }
448  return p;// expected-warning {{Allocated memory never released. Potential memory leak.}}
449}
450