malloc.c revision 783f0087ecb5af27d2f8caed7d6b904797c3d752
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.deadcode.UnreachableCode,experimental.core.CastSize,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 *valloc(size_t);
7void free(void *);
8void *realloc(void *ptr, size_t size);
9void *reallocf(void *ptr, size_t size);
10void *calloc(size_t nmemb, size_t size);
11char *strdup(const char *s);
12char *strndup(const char *s, size_t n);
13
14void myfoo(int *p);
15void myfooint(int p);
16char *fooRetPtr();
17
18void f1() {
19  int *p = malloc(12);
20  return; // expected-warning{{Memory is never released; potential leak}}
21}
22
23void f2() {
24  int *p = malloc(12);
25  free(p);
26  free(p); // expected-warning{{Attempt to free released memory}}
27}
28
29void f2_realloc_0() {
30  int *p = malloc(12);
31  realloc(p,0);
32  realloc(p,0); // expected-warning{{Attempt to free released memory}}
33}
34
35void f2_realloc_1() {
36  int *p = malloc(12);
37  int *q = realloc(p,0); // no-warning
38}
39
40void reallocNotNullPtr(unsigned sizeIn) {
41  unsigned size = 12;
42  char *p = (char*)malloc(size);
43  if (p) {
44    char *q = (char*)realloc(p, sizeIn);
45    char x = *q; // expected-warning {{Memory is never released; potential leak}}
46  }
47}
48
49int *realloctest1() {
50  int *q = malloc(12);
51  q = realloc(q, 20);
52  return q; // no warning - returning the allocated value
53}
54
55// p should be freed if realloc fails.
56void reallocFails() {
57  char *p = malloc(12);
58  char *r = realloc(p, 12+1);
59  if (!r) {
60    free(p);
61  } else {
62    free(r);
63  }
64}
65
66void reallocSizeZero1() {
67  char *p = malloc(12);
68  char *r = realloc(p, 0);
69  if (!r) {
70    free(p);
71  } else {
72    free(r);
73  }
74}
75
76void reallocSizeZero2() {
77  char *p = malloc(12);
78  char *r = realloc(p, 0);
79  if (!r) {
80    free(p);
81  } else {
82    free(r);
83  }
84  free(p); // expected-warning {{Attempt to free released memory}}
85}
86
87void reallocSizeZero3() {
88  char *p = malloc(12);
89  char *r = realloc(p, 0);
90  free(r);
91}
92
93void reallocSizeZero4() {
94  char *r = realloc(0, 0);
95  free(r);
96}
97
98void reallocSizeZero5() {
99  char *r = realloc(0, 0);
100}
101
102void reallocPtrZero1() {
103  char *r = realloc(0, 12); // expected-warning {{Memory is never released; potential leak}}
104}
105
106void reallocPtrZero2() {
107  char *r = realloc(0, 12);
108  if (r)
109    free(r);
110}
111
112void reallocPtrZero3() {
113  char *r = realloc(0, 12);
114  free(r);
115}
116
117void reallocRadar6337483_1() {
118    char *buf = malloc(100);
119    buf = (char*)realloc(buf, 0x1000000);
120    if (!buf) {
121        return;// expected-warning {{Memory is never released; potential leak}}
122    }
123    free(buf);
124}
125
126void reallocRadar6337483_2() {
127    char *buf = malloc(100);
128    char *buf2 = (char*)realloc(buf, 0x1000000);
129    if (!buf2) { // expected-warning {{Memory is never released; potential leak}}
130      ;
131    } else {
132      free(buf2);
133    }
134}
135
136void reallocRadar6337483_3() {
137    char * buf = malloc(100);
138    char * tmp;
139    tmp = (char*)realloc(buf, 0x1000000);
140    if (!tmp) {
141        free(buf);
142        return;
143    }
144    buf = tmp;
145    free(buf);
146}
147
148void reallocRadar6337483_4() {
149    char *buf = malloc(100);
150    char *buf2 = (char*)realloc(buf, 0x1000000);
151    if (!buf2) {
152      return;  // expected-warning {{Memory is never released; potential leak}}
153    } else {
154      free(buf2);
155    }
156}
157
158int *reallocfTest1() {
159  int *q = malloc(12);
160  q = reallocf(q, 20);
161  return q; // no warning - returning the allocated value
162}
163
164void reallocfRadar6337483_4() {
165    char *buf = malloc(100);
166    char *buf2 = (char*)reallocf(buf, 0x1000000);
167    if (!buf2) {
168      return;  // no warning - reallocf frees even on failure
169    } else {
170      free(buf2);
171    }
172}
173
174void reallocfRadar6337483_3() {
175    char * buf = malloc(100);
176    char * tmp;
177    tmp = (char*)reallocf(buf, 0x1000000);
178    if (!tmp) {
179        free(buf); // expected-warning {{Attempt to free released memory}}
180        return;
181    }
182    buf = tmp;
183    free(buf);
184}
185
186void reallocfPtrZero1() {
187  char *r = reallocf(0, 12); // expected-warning {{Memory is never released; potential leak}}
188}
189
190
191// This case tests that storing malloc'ed memory to a static variable which is
192// then returned is not leaked.  In the absence of known contracts for functions
193// or inter-procedural analysis, this is a conservative answer.
194int *f3() {
195  static int *p = 0;
196  p = malloc(12);
197  return p; // no-warning
198}
199
200// This case tests that storing malloc'ed memory to a static global variable
201// which is then returned is not leaked.  In the absence of known contracts for
202// functions or inter-procedural analysis, this is a conservative answer.
203static int *p_f4 = 0;
204int *f4() {
205  p_f4 = malloc(12);
206  return p_f4; // no-warning
207}
208
209int *f5() {
210  int *q = malloc(12);
211  q = realloc(q, 20);
212  return q; // no-warning
213}
214
215void f6() {
216  int *p = malloc(12);
217  if (!p)
218    return; // no-warning
219  else
220    free(p);
221}
222
223void f6_realloc() {
224  int *p = malloc(12);
225  if (!p)
226    return; // no-warning
227  else
228    realloc(p,0);
229}
230
231
232char *doit2();
233void pr6069() {
234  char *buf = doit2();
235  free(buf);
236}
237
238void pr6293() {
239  free(0);
240}
241
242void f7() {
243  char *x = (char*) malloc(4);
244  free(x);
245  x[0] = 'a'; // expected-warning{{Use of memory after it is freed}}
246}
247
248void f8() {
249  char *x = (char*) malloc(4);
250  free(x);
251  char *y = strndup(x, 4); // expected-warning{{Use of memory after it is freed}}
252}
253
254void f7_realloc() {
255  char *x = (char*) malloc(4);
256  realloc(x,0);
257  x[0] = 'a'; // expected-warning{{Use of memory after it is freed}}
258}
259
260void PR6123() {
261  int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}}
262}
263
264void PR7217() {
265  int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}}
266  buf[1] = 'c'; // not crash
267}
268
269void mallocCastToVoid() {
270  void *p = malloc(2);
271  const void *cp = p; // not crash
272  free(p);
273}
274
275void mallocCastToFP() {
276  void *p = malloc(2);
277  void (*fp)() = p; // not crash
278  free(p);
279}
280
281// This tests that malloc() buffers are undefined by default
282char mallocGarbage () {
283	char *buf = malloc(2);
284	char result = buf[1]; // expected-warning{{undefined}}
285	free(buf);
286	return result;
287}
288
289// This tests that calloc() buffers need to be freed
290void callocNoFree () {
291  char *buf = calloc(2,2);
292  return; // expected-warning{{never released}}
293}
294
295// These test that calloc() buffers are zeroed by default
296char callocZeroesGood () {
297	char *buf = calloc(2,2);
298	char result = buf[3]; // no-warning
299	if (buf[1] == 0) {
300	  free(buf);
301	}
302	return result; // no-warning
303}
304
305char callocZeroesBad () {
306	char *buf = calloc(2,2);
307	char result = buf[3]; // no-warning
308	if (buf[1] != 0) {
309	  free(buf); // expected-warning{{never executed}}
310	}
311	return result; // expected-warning{{never released}}
312}
313
314void nullFree() {
315  int *p = 0;
316  free(p); // no warning - a nop
317}
318
319void paramFree(int *p) {
320  myfoo(p);
321  free(p); // no warning
322  myfoo(p); // TODO: This should be a warning.
323}
324
325int* mallocEscapeRet() {
326  int *p = malloc(12);
327  return p; // no warning
328}
329
330void mallocEscapeFoo() {
331  int *p = malloc(12);
332  myfoo(p);
333  return; // no warning
334}
335
336void mallocEscapeFree() {
337  int *p = malloc(12);
338  myfoo(p);
339  free(p);
340}
341
342void mallocEscapeFreeFree() {
343  int *p = malloc(12);
344  myfoo(p);
345  free(p);
346  free(p); // expected-warning{{Attempt to free released memory}}
347}
348
349void mallocEscapeFreeUse() {
350  int *p = malloc(12);
351  myfoo(p);
352  free(p);
353  myfoo(p); // expected-warning{{Use of memory after it is freed}}
354}
355
356int *myalloc();
357void myalloc2(int **p);
358
359void mallocEscapeFreeCustomAlloc() {
360  int *p = malloc(12);
361  myfoo(p);
362  free(p);
363  p = myalloc();
364  free(p); // no warning
365}
366
367void mallocEscapeFreeCustomAlloc2() {
368  int *p = malloc(12);
369  myfoo(p);
370  free(p);
371  myalloc2(&p);
372  free(p); // no warning
373}
374
375void mallocBindFreeUse() {
376  int *x = malloc(12);
377  int *y = x;
378  free(y);
379  myfoo(x); // expected-warning{{Use of memory after it is freed}}
380}
381
382void mallocEscapeMalloc() {
383  int *p = malloc(12);
384  myfoo(p);
385  p = malloc(12); // expected-warning{{Memory is never released; potential leak}}
386}
387
388void mallocMalloc() {
389  int *p = malloc(12);
390  p = malloc(12); // expected-warning 2 {{Memory is never released; potential leak}}
391}
392
393void mallocFreeMalloc() {
394  int *p = malloc(12);
395  free(p);
396  p = malloc(12);
397  free(p);
398}
399
400void mallocFreeUse_params() {
401  int *p = malloc(12);
402  free(p);
403  myfoo(p); //expected-warning{{Use of memory after it is freed}}
404}
405
406void mallocFreeUse_params2() {
407  int *p = malloc(12);
408  free(p);
409  myfooint(*p); //expected-warning{{Use of memory after it is freed}}
410}
411
412void mallocFailedOrNot() {
413  int *p = malloc(12);
414  if (!p)
415    free(p);
416  else
417    free(p);
418}
419
420struct StructWithInt {
421  int g;
422};
423
424int *mallocReturnFreed() {
425  int *p = malloc(12);
426  free(p);
427  return p; // expected-warning {{Use of memory after it is freed}}
428}
429
430int useAfterFreeStruct() {
431  struct StructWithInt *px= malloc(sizeof(struct StructWithInt));
432  px->g = 5;
433  free(px);
434  return px->g; // expected-warning {{Use of memory after it is freed}}
435}
436
437void nonSymbolAsFirstArg(int *pp, struct StructWithInt *p);
438
439void mallocEscapeFooNonSymbolArg() {
440  struct StructWithInt *p = malloc(sizeof(struct StructWithInt));
441  nonSymbolAsFirstArg(&p->g, p);
442  return; // no warning
443}
444
445void mallocFailedOrNotLeak() {
446  int *p = malloc(12);
447  if (p == 0)
448    return; // no warning
449  else
450    return; // expected-warning {{Memory is never released; potential leak}}
451}
452
453void mallocAssignment() {
454  char *p = malloc(12);
455  p = fooRetPtr(); // expected-warning {{leak}}
456}
457
458int vallocTest() {
459  char *mem = valloc(12);
460  return 0; // expected-warning {{Memory is never released; potential leak}}
461}
462
463void vallocEscapeFreeUse() {
464  int *p = valloc(12);
465  myfoo(p);
466  free(p);
467  myfoo(p); // expected-warning{{Use of memory after it is freed}}
468}
469
470int *Gl;
471struct GlStTy {
472  int *x;
473};
474
475struct GlStTy GlS = {0};
476
477void GlobalFree() {
478  free(Gl);
479}
480
481void GlobalMalloc() {
482  Gl = malloc(12);
483}
484
485void GlobalStructMalloc() {
486  int *a = malloc(12);
487  GlS.x = a;
488}
489
490void GlobalStructMallocFree() {
491  int *a = malloc(12);
492  GlS.x = a;
493  free(GlS.x);
494}
495
496char *ArrayG[12];
497
498void globalArrayTest() {
499  char *p = (char*)malloc(12);
500  ArrayG[0] = p;
501}
502
503// Make sure that we properly handle a pointer stored into a local struct/array.
504typedef struct _StructWithPtr {
505  int *memP;
506} StructWithPtr;
507
508static StructWithPtr arrOfStructs[10];
509
510void testMalloc() {
511  int *x = malloc(12);
512  StructWithPtr St;
513  St.memP = x;
514  arrOfStructs[0] = St;
515}
516
517StructWithPtr testMalloc2() {
518  int *x = malloc(12);
519  StructWithPtr St;
520  St.memP = x;
521  return St;
522}
523
524int *testMalloc3() {
525  int *x = malloc(12);
526  int *y = x;
527  return y;
528}
529
530void testElemRegion1() {
531  char *x = (void*)malloc(2);
532  int *ix = (int*)x;
533  free(&(x[0]));
534}
535
536void testElemRegion2(int **pp) {
537  int *p = malloc(12);
538  *pp = p;
539  free(pp[0]);
540}
541
542void testElemRegion3(int **pp) {
543  int *p = malloc(12);
544  *pp = p;
545  free(*pp);
546}
547// Region escape testing.
548
549unsigned takePtrToPtr(int **p);
550void PassTheAddrOfAllocatedData(int f) {
551  int *p = malloc(12);
552  // We don't know what happens after the call. Should stop tracking here.
553  if (takePtrToPtr(&p))
554    f++;
555  free(p); // no warning
556}
557
558struct X {
559  int *p;
560};
561unsigned takePtrToStruct(struct X *s);
562int ** foo2(int *g, int f) {
563  int *p = malloc(12);
564  struct X *px= malloc(sizeof(struct X));
565  px->p = p;
566  // We don't know what happens after this call. Should not track px nor p.
567  if (takePtrToStruct(px))
568    f++;
569  free(p);
570  return 0;
571}
572
573struct X* RegInvalidationDetect1(struct X *s2) {
574  struct X *px= malloc(sizeof(struct X));
575  px->p = 0;
576  px = s2;
577  return px; // expected-warning {{Memory is never released; potential leak}}
578}
579
580struct X* RegInvalidationGiveUp1() {
581  int *p = malloc(12);
582  struct X *px= malloc(sizeof(struct X));
583  px->p = p;
584  return px;
585}
586
587int **RegInvalidationDetect2(int **pp) {
588  int *p = malloc(12);
589  pp = &p;
590  pp++;
591  return 0;// expected-warning {{Memory is never released; potential leak}}
592}
593
594extern void exit(int) __attribute__ ((__noreturn__));
595void mallocExit(int *g) {
596  struct xx *p = malloc(12);
597  if (g != 0)
598    exit(1);
599  free(p);
600  return;
601}
602
603extern void __assert_fail (__const char *__assertion, __const char *__file,
604    unsigned int __line, __const char *__function)
605     __attribute__ ((__noreturn__));
606#define assert(expr) \
607  ((expr)  ? (void)(0)  : __assert_fail (#expr, __FILE__, __LINE__, __func__))
608void mallocAssert(int *g) {
609  struct xx *p = malloc(12);
610
611  assert(g != 0);
612  free(p);
613  return;
614}
615
616void doNotInvalidateWhenPassedToSystemCalls(char *s) {
617  char *p = malloc(12);
618  strlen(p);
619  strcpy(p, s); // expected-warning {{leak}}
620}
621
622// Rely on the CString checker evaluation of the strcpy API to convey that the result of strcpy is equal to p.
623void symbolLostWithStrcpy(char *s) {
624  char *p = malloc(12);
625  p = strcpy(p, s);
626  free(p);
627}
628
629
630// The same test as the one above, but with what is actually generated on a mac.
631static __inline char *
632__inline_strcpy_chk (char *restrict __dest, const char *restrict __src)
633{
634  return __builtin___strcpy_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1));
635}
636
637void symbolLostWithStrcpy_InlineStrcpyVersion(char *s) {
638  char *p = malloc(12);
639  p = ((__builtin_object_size (p, 0) != (size_t) -1) ? __builtin___strcpy_chk (p, s, __builtin_object_size (p, 2 > 1)) : __inline_strcpy_chk (p, s));
640  free(p);
641}
642
643// Here we are returning a pointer one past the allocated value. An idiom which
644// can be used for implementing special malloc. The correct uses of this might
645// be rare enough so that we could keep this as a warning.
646static void *specialMalloc(int n){
647  int *p;
648  p = malloc( n+8 );
649  if( p ){
650    p[0] = n;
651    p++;
652  }
653  return p;
654}
655
656// Potentially, the user could free the struct by performing pointer arithmetic on the return value.
657// This is a variation of the specialMalloc issue, though probably would be more rare in correct code.
658int *specialMallocWithStruct() {
659  struct StructWithInt *px= malloc(sizeof(struct StructWithInt));
660  return &(px->g);
661}
662
663// Test various allocation/deallocation functions.
664void testStrdup(const char *s, unsigned validIndex) {
665  char *s2 = strdup(s);
666  s2[validIndex + 1] = 'b';// expected-warning {{Memory is never released; potential leak}}
667}
668
669int testStrndup(const char *s, unsigned validIndex, unsigned size) {
670  char *s2 = strndup(s, size);
671  s2 [validIndex + 1] = 'b';
672  if (s2[validIndex] != 'a')
673    return 0;
674  else
675    return 1;// expected-warning {{Memory is never released; potential leak}}
676}
677
678void testStrdupContentIsDefined(const char *s, unsigned validIndex) {
679  char *s2 = strdup(s);
680  char result = s2[1];// no warning
681  free(s2);
682}
683
684// ----------------------------------------------------------------------------
685// Test the system library functions to which the pointer can escape.
686// This tests false positive suppression.
687
688// For now, we assume memory passed to pthread_specific escapes.
689// TODO: We could check that if a new pthread binding is set, the existing
690// binding must be freed; otherwise, a memory leak can occur.
691void testPthereadSpecificEscape(pthread_key_t key) {
692  void *buf = malloc(12);
693  pthread_setspecific(key, buf); // no warning
694}
695
696// PR12101: Test funopen().
697static int releasePtr(void *_ctx) {
698    free(_ctx);
699    return 0;
700}
701FILE *useFunOpen() {
702    void *ctx = malloc(sizeof(int));
703    FILE *f = funopen(ctx, 0, 0, 0, releasePtr); // no warning
704    if (f == 0) {
705        free(ctx);
706    }
707    return f;
708}
709FILE *useFunOpenNoReleaseFunction() {
710    void *ctx = malloc(sizeof(int));
711    FILE *f = funopen(ctx, 0, 0, 0, 0);
712    if (f == 0) {
713        free(ctx);
714    }
715    return f; // expected-warning{{leak}}
716}
717
718// Test setbuf, setvbuf.
719int my_main_no_warning() {
720    char *p = malloc(100);
721    setvbuf(stdout, p, 0, 100);
722    return 0;
723}
724int my_main_no_warning2() {
725    char *p = malloc(100);
726    setbuf(__stdoutp, p);
727    return 0;
728}
729int my_main_warn(FILE *f) {
730    char *p = malloc(100);
731    setvbuf(f, p, 0, 100);
732    return 0;// expected-warning {{leak}}
733}
734
735// <rdar://problem/10978247>.
736// some people use stack allocated memory as an optimization to avoid
737// a heap allocation for small work sizes.  This tests the analyzer's
738// understanding that the malloc'ed memory is not the same as stackBuffer.
739void radar10978247(int myValueSize) {
740  char stackBuffer[128];
741  char *buffer;
742
743  if (myValueSize <= sizeof(stackBuffer))
744    buffer = stackBuffer;
745  else
746    buffer = malloc(myValueSize);
747
748  // do stuff with the buffer
749  if (buffer != stackBuffer)
750    free(buffer);
751}
752
753void radar10978247_positive(int myValueSize) {
754  char stackBuffer[128];
755  char *buffer;
756
757  if (myValueSize <= sizeof(stackBuffer))
758    buffer = stackBuffer;
759  else
760    buffer = malloc(myValueSize);
761
762  // do stuff with the buffer
763  if (buffer == stackBuffer) // expected-warning {{leak}}
764    return;
765}
766
767// <rdar://problem/11269741> Previously this triggered a false positive
768// because malloc() is known to return uninitialized memory and the binding
769// of 'o' to 'p->n' was not getting propertly handled.  Now we report a leak.
770struct rdar11269741_a_t {
771  struct rdar11269741_b_t {
772    int m;
773  } n;
774};
775
776int rdar11269741(struct rdar11269741_b_t o)
777{
778  struct rdar11269741_a_t *p = (struct rdar11269741_a_t *) malloc(sizeof(*p));
779  p->n = o;
780  return p->n.m; // expected-warning {{leak}}
781}
782
783// Pointer arithmetic, returning an ElementRegion.
784void *radar11329382(unsigned bl) {
785  void *ptr = malloc (16);
786  ptr = ptr + (2 - bl);
787  return ptr; // no warning
788}
789
790void __assert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__));
791int strcmp(const char *, const char *);
792char *a (void);
793void radar11270219(void) {
794  char *x = a(), *y = a();
795  (__builtin_expect(!(x && y), 0) ? __assert_rtn(__func__, "/Users/zaks/tmp/ex.c", 24, "x && y") : (void)0);
796  strcmp(x, y); // no warning
797}
798
799void radar_11358224_test_double_assign_ints_positive_2()
800{
801  void *ptr = malloc(16);
802  ptr = ptr; // expected-warning {{leak}}
803}
804
805// Assume that functions which take a function pointer can free memory even if
806// they are defined in system headers and take the const pointer to the
807// allocated memory. (radar://11160612)
808int const_ptr_and_callback(int, const char*, int n, void(*)(void*));
809void r11160612_1() {
810  char *x = malloc(12);
811  const_ptr_and_callback(0, x, 12, free); // no - warning
812}
813
814// Null is passed as callback.
815void r11160612_2() {
816  char *x = malloc(12);
817  const_ptr_and_callback(0, x, 12, 0); // expected-warning {{leak}}
818}
819
820// Callback is passed to a function defined in a system header.
821void r11160612_4() {
822  char *x = malloc(12);
823  sqlite3_bind_text_my(0, x, 12, free); // no - warning
824}
825
826// Passing callbacks in a struct.
827void r11160612_5(StWithCallback St) {
828  void *x = malloc(12);
829  dealocateMemWhenDoneByVal(x, St);
830}
831void r11160612_6(StWithCallback St) {
832  void *x = malloc(12);
833  dealocateMemWhenDoneByRef(&St, x);
834}
835
836int mySub(int, int);
837int myAdd(int, int);
838int fPtr(unsigned cond, int x) {
839  return (cond ? mySub : myAdd)(x, x);
840}
841
842// Test anti-aliasing.
843
844void dependsOnValueOfPtr(int *g, unsigned f) {
845  int *p;
846
847  if (f) {
848    p = g;
849  } else {
850    p = malloc(12);
851  }
852
853  if (p != g)
854    free(p);
855  else
856    return; // no warning
857  return;
858}
859
860int CMPRegionHeapToStack() {
861  int x = 0;
862  int *x1 = malloc(8);
863  int *x2 = &x;
864  if (x1 == x2)
865    return 5/x; // expected-warning{{This statement is never executed}}
866  free(x1);
867  return x;
868}
869
870int CMPRegionHeapToHeap2() {
871  int x = 0;
872  int *x1 = malloc(8);
873  int *x2 = malloc(8);
874  int *x4 = x1;
875  int *x5 = x2;
876  if (x4 == x5)
877    return 5/x; // expected-warning{{This statement is never executed}}
878  free(x1);
879  free(x2);
880  return x;
881}
882
883int CMPRegionHeapToHeap() {
884  int x = 0;
885  int *x1 = malloc(8);
886  int *x4 = x1;
887  if (x1 == x4) {
888    free(x1);
889    return 5/x; // expected-warning{{Division by zero}}
890  }
891  return x;// expected-warning{{This statement is never executed}}
892}
893
894int HeapAssignment() {
895  int m = 0;
896  int *x = malloc(4);
897  int *y = x;
898  *x = 5;
899  if (*x != *y)
900    return 5/m; // expected-warning{{This statement is never executed}}
901  free(x);
902  return 0;
903}
904
905int *retPtr();
906int *retPtrMightAlias(int *x);
907int cmpHeapAllocationToUnknown() {
908  int zero = 0;
909  int *yBefore = retPtr();
910  int *m = malloc(8);
911  int *yAfter = retPtrMightAlias(m);
912  if (yBefore == m) {
913    return 5/zero; // expected-warning {{This statement is never executed}}
914  }
915  if (yAfter == m) {
916    return 5/zero; // expected-warning {{This statement is never executed}}
917  }
918  free(m);
919  return 0;
920}
921
922// ----------------------------------------------------------------------------
923// False negatives.
924
925// TODO: This requires tracking symbols stored inside the structs/arrays.
926void testMalloc5() {
927  StructWithPtr St;
928  StructWithPtr *pSt = &St;
929  pSt->memP = malloc(12);
930}
931
932// TODO: This is another false negative.
933void testMallocWithParam(int **p) {
934  *p = (int*) malloc(sizeof(int));
935  *p = 0;
936}
937
938void testMallocWithParam_2(int **p) {
939  *p = (int*) malloc(sizeof(int));
940}
941
942// TODO: This should produce a warning, similar to the previous issue.
943void localArrayTest() {
944  char *p = (char*)malloc(12);
945  char *ArrayL[12];
946  ArrayL[0] = p;
947}
948
949// Test double assignment through integers.
950static long glob;
951void test_double_assign_ints()
952{
953  void *ptr = malloc (16);  // no-warning
954  glob = (long)(unsigned long)ptr;
955}
956
957void test_double_assign_ints_positive()
958{
959  void *ptr = malloc(16);
960  (void*)(long)(unsigned long)ptr; // expected-warning {{unused}} expected-warning {{leak}}
961}
962
963