malloc.c revision b276bd9cc98247331cac8b290ba278b939e53657
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
61void reallocSizeZero1() {
62  char *p = malloc(12);
63  char *r = realloc(p, 0);
64  if (!r) {
65    free(p);
66  } else {
67    free(r);
68  }
69}
70
71void reallocSizeZero2() {
72  char *p = malloc(12);
73  char *r = realloc(p, 0);
74  if (!r) {
75    free(p);
76  } else {
77    free(r);
78  }
79  free(p); // expected-warning {{Try to free a memory block that has been released}}
80}
81
82void reallocSizeZero3() {
83  char *p = malloc(12);
84  char *r = realloc(p, 0);
85  free(r);
86}
87
88void reallocSizeZero4() {
89  char *r = realloc(0, 0);
90  free(r);
91}
92
93void reallocSizeZero5() {
94  char *r = realloc(0, 0);
95}
96
97void reallocPtrZero1() {
98  char *r = realloc(0, 12); // expected-warning {{Allocated memory never released.}}
99}
100
101void reallocPtrZero2() {
102  char *r = realloc(0, 12);
103  if (r)
104    free(r);
105}
106
107void reallocPtrZero3() {
108  char *r = realloc(0, 12);
109  free(r);
110}
111
112void reallocRadar6337483_1() {
113    char *buf = malloc(100);
114    buf = (char*)realloc(buf, 0x1000000);
115    if (!buf) {
116        return;// expected-warning {{Allocated memory never released.}}
117    }
118    free(buf);
119}
120
121void reallocRadar6337483_2() {
122    char *buf = malloc(100);
123    char *buf2 = (char*)realloc(buf, 0x1000000);
124    if (!buf2) { // expected-warning {{Allocated memory never released.}}
125      ;
126    } else {
127      free(buf2);
128    }
129}
130
131void reallocRadar6337483_3() {
132    char * buf = malloc(100);
133    char * tmp;
134    tmp = (char*)realloc(buf, 0x1000000);
135    if (!tmp) {
136        free(buf);
137        return;
138    }
139    buf = tmp;
140    free(buf);
141}
142
143void reallocRadar6337483_4() {
144    char *buf = malloc(100);
145    char *buf2 = (char*)realloc(buf, 0x1000000);
146    if (!buf2) {
147      return;  // expected-warning {{Allocated memory never released.}}
148    } else {
149      free(buf2);
150    }
151}
152
153// This case tests that storing malloc'ed memory to a static variable which is
154// then returned is not leaked.  In the absence of known contracts for functions
155// or inter-procedural analysis, this is a conservative answer.
156int *f3() {
157  static int *p = 0;
158  p = malloc(12);
159  return p; // no-warning
160}
161
162// This case tests that storing malloc'ed memory to a static global variable
163// which is then returned is not leaked.  In the absence of known contracts for
164// functions or inter-procedural analysis, this is a conservative answer.
165static int *p_f4 = 0;
166int *f4() {
167  p_f4 = malloc(12);
168  return p_f4; // no-warning
169}
170
171int *f5() {
172  int *q = malloc(12);
173  q = realloc(q, 20);
174  return q; // no-warning
175}
176
177void f6() {
178  int *p = malloc(12);
179  if (!p)
180    return; // no-warning
181  else
182    free(p);
183}
184
185void f6_realloc() {
186  int *p = malloc(12);
187  if (!p)
188    return; // no-warning
189  else
190    realloc(p,0);
191}
192
193
194char *doit2();
195void pr6069() {
196  char *buf = doit2();
197  free(buf);
198}
199
200void pr6293() {
201  free(0);
202}
203
204void f7() {
205  char *x = (char*) malloc(4);
206  free(x);
207  x[0] = 'a'; // expected-warning{{Use of dynamically allocated memory after it is freed.}}
208}
209
210void f7_realloc() {
211  char *x = (char*) malloc(4);
212  realloc(x,0);
213  x[0] = 'a'; // expected-warning{{Use of dynamically allocated memory after it is freed.}}
214}
215
216void PR6123() {
217  int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}}
218}
219
220void PR7217() {
221  int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}}
222  buf[1] = 'c'; // not crash
223}
224
225void mallocCastToVoid() {
226  void *p = malloc(2);
227  const void *cp = p; // not crash
228  free(p);
229}
230
231void mallocCastToFP() {
232  void *p = malloc(2);
233  void (*fp)() = p; // not crash
234  free(p);
235}
236
237// This tests that malloc() buffers are undefined by default
238char mallocGarbage () {
239	char *buf = malloc(2);
240	char result = buf[1]; // expected-warning{{undefined}}
241	free(buf);
242	return result;
243}
244
245// This tests that calloc() buffers need to be freed
246void callocNoFree () {
247  char *buf = calloc(2,2);
248  return; // expected-warning{{never released}}
249}
250
251// These test that calloc() buffers are zeroed by default
252char callocZeroesGood () {
253	char *buf = calloc(2,2);
254	char result = buf[3]; // no-warning
255	if (buf[1] == 0) {
256	  free(buf);
257	}
258	return result; // no-warning
259}
260
261char callocZeroesBad () {
262	char *buf = calloc(2,2);
263	char result = buf[3]; // no-warning
264	if (buf[1] != 0) {
265	  free(buf); // expected-warning{{never executed}}
266	}
267	return result; // expected-warning{{never released}}
268}
269
270void nullFree() {
271  int *p = 0;
272  free(p); // no warning - a nop
273}
274
275void paramFree(int *p) {
276  myfoo(p);
277  free(p); // no warning
278  myfoo(p); // TODO: This should be a warning.
279}
280
281int* mallocEscapeRet() {
282  int *p = malloc(12);
283  return p; // no warning
284}
285
286void mallocEscapeFoo() {
287  int *p = malloc(12);
288  myfoo(p);
289  return; // no warning
290}
291
292void mallocEscapeFree() {
293  int *p = malloc(12);
294  myfoo(p);
295  free(p);
296}
297
298void mallocEscapeFreeFree() {
299  int *p = malloc(12);
300  myfoo(p);
301  free(p);
302  free(p); // expected-warning{{Try to free a memory block that has been released}}
303}
304
305void mallocEscapeFreeUse() {
306  int *p = malloc(12);
307  myfoo(p);
308  free(p);
309  myfoo(p); // expected-warning{{Use of dynamically allocated memory after it is freed.}}
310}
311
312int *myalloc();
313void myalloc2(int **p);
314
315void mallocEscapeFreeCustomAlloc() {
316  int *p = malloc(12);
317  myfoo(p);
318  free(p);
319  p = myalloc();
320  free(p); // no warning
321}
322
323void mallocEscapeFreeCustomAlloc2() {
324  int *p = malloc(12);
325  myfoo(p);
326  free(p);
327  myalloc2(&p);
328  free(p); // no warning
329}
330
331void mallocBindFreeUse() {
332  int *x = malloc(12);
333  int *y = x;
334  free(y);
335  myfoo(x); // expected-warning{{Use of dynamically allocated memory after it is freed.}}
336}
337
338void mallocEscapeMalloc() {
339  int *p = malloc(12);
340  myfoo(p);
341  p = malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak.}}
342}
343
344void mallocMalloc() {
345  int *p = malloc(12);
346  p = malloc(12); // expected-warning{{Allocated memory never released. Potential memory leak}}
347}
348
349void mallocFreeMalloc() {
350  int *p = malloc(12);
351  free(p);
352  p = malloc(12);
353  free(p);
354}
355
356void mallocFreeUse_params() {
357  int *p = malloc(12);
358  free(p);
359  myfoo(p); //expected-warning{{Use of dynamically allocated memory after it is freed}}
360}
361
362void mallocFreeUse_params2() {
363  int *p = malloc(12);
364  free(p);
365  myfooint(*p); //expected-warning{{Use of dynamically allocated memory after it is freed}}
366}
367
368void mallocFailedOrNot() {
369  int *p = malloc(12);
370  if (!p)
371    free(p);
372  else
373    free(p);
374}
375
376struct StructWithInt {
377  int g;
378};
379
380int *mallocReturnFreed() {
381  int *p = malloc(12);
382  free(p);
383  return p; // expected-warning {{Use of dynamically allocated}}
384}
385
386int useAfterFreeStruct() {
387  struct StructWithInt *px= malloc(sizeof(struct StructWithInt));
388  px->g = 5;
389  free(px);
390  return px->g; // expected-warning {{Use of dynamically allocated}}
391}
392
393void nonSymbolAsFirstArg(int *pp, struct StructWithInt *p);
394
395void mallocEscapeFooNonSymbolArg() {
396  struct StructWithInt *p = malloc(sizeof(struct StructWithInt));
397  nonSymbolAsFirstArg(&p->g, p);
398  return; // no warning
399}
400
401void mallocFailedOrNotLeak() {
402  int *p = malloc(12);
403  if (p == 0)
404    return; // no warning
405  else
406    return; // expected-warning {{Allocated memory never released. Potential memory leak.}}
407}
408
409int *Gl;
410struct GlStTy {
411  int *x;
412};
413
414struct GlStTy GlS = {0};
415
416void GlobalFree() {
417  free(Gl);
418}
419
420void GlobalMalloc() {
421  Gl = malloc(12);
422}
423
424void GlobalStructMalloc() {
425  int *a = malloc(12);
426  GlS.x = a;
427}
428
429void GlobalStructMallocFree() {
430  int *a = malloc(12);
431  GlS.x = a;
432  free(GlS.x);
433}
434
435// Region escape testing.
436
437unsigned takePtrToPtr(int **p);
438void PassTheAddrOfAllocatedData(int f) {
439  int *p = malloc(12);
440  // We don't know what happens after the call. Should stop tracking here.
441  if (takePtrToPtr(&p))
442    f++;
443  free(p); // no warning
444}
445
446struct X {
447  int *p;
448};
449unsigned takePtrToStruct(struct X *s);
450int ** foo2(int *g, int f) {
451  int *p = malloc(12);
452  struct X *px= malloc(sizeof(struct X));
453  px->p = p;
454  // We don't know what happens after this call. Should not track px nor p.
455  if (takePtrToStruct(px))
456    f++;
457  free(p);
458  return 0;
459}
460
461struct X* RegInvalidationDetect1(struct X *s2) {
462  struct X *px= malloc(sizeof(struct X));
463  px->p = 0;
464  px = s2;
465  return px; // expected-warning {{Allocated memory never released. Potential memory leak.}}
466}
467
468struct X* RegInvalidationGiveUp1() {
469  int *p = malloc(12);
470  struct X *px= malloc(sizeof(struct X));
471  px->p = p;
472  return px;
473}
474
475int **RegInvalidationDetect2(int **pp) {
476  int *p = malloc(12);
477  pp = &p;
478  pp++;
479  return 0;// expected-warning {{Allocated memory never released. Potential memory leak.}}
480}
481
482extern void exit(int) __attribute__ ((__noreturn__));
483void mallocExit(int *g) {
484  struct xx *p = malloc(12);
485  if (g != 0)
486    exit(1);
487  free(p);
488  return;
489}
490
491extern void __assert_fail (__const char *__assertion, __const char *__file,
492    unsigned int __line, __const char *__function)
493     __attribute__ ((__noreturn__));
494#define assert(expr) \
495  ((expr)  ? (void)(0)  : __assert_fail (#expr, __FILE__, __LINE__, __func__))
496void mallocAssert(int *g) {
497  struct xx *p = malloc(12);
498
499  assert(g != 0);
500  free(p);
501  return;
502}
503
504void doNotInvalidateWhenPassedToSystemCalls(char *s) {
505  char *p = malloc(12);
506  strlen(p);
507  strcpy(p, s); // expected-warning {{leak}}
508}
509
510// Below are the known false positives.
511
512// TODO: There should be no warning here. This one might be difficult to get rid of.
513void dependsOnValueOfPtr(int *g, unsigned f) {
514  int *p;
515
516  if (f) {
517    p = g;
518  } else {
519    p = malloc(12);
520  }
521
522  if (p != g)
523    free(p);
524  else
525    return; // expected-warning{{Allocated memory never released. Potential memory leak}}
526  return;
527}
528
529// TODO: Should this be a warning?
530// Here we are returning a pointer one past the allocated value. An idiom which
531// can be used for implementing special malloc. The correct uses of this might
532// be rare enough so that we could keep this as a warning.
533static void *specialMalloc(int n){
534  int *p;
535  p = malloc( n+8 );
536  if( p ){
537    p[0] = n;
538    p++;
539  }
540  return p;// expected-warning {{Allocated memory never released. Potential memory leak.}}
541}
542