1 // RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc -analyzer-inline-max-stack-depth=5 -analyzer-inline-max-function-size=6 -verify %s
2 
3 #include "Inputs/system-header-simulator.h"
4 
5 typedef __typeof(sizeof(int)) size_t;
6 void *malloc(size_t);
7 void *valloc(size_t);
8 void free(void *);
9 void *realloc(void *ptr, size_t size);
10 void *reallocf(void *ptr, size_t size);
11 void *calloc(size_t nmemb, size_t size);
12 extern void exit(int) __attribute__ ((__noreturn__));
13 
14 static void my_malloc1(void **d, size_t size) {
15   *d = malloc(size);
16 }
17 
18 static void *my_malloc2(int elevel, size_t size) {
19   void     *data;
20   data = malloc(size);
21   if (data == 0)
22     exit(0);
23   return data;
24 }
25 
26 static void my_free1(void *p) {
27   free(p);
28 }
29 
30 static void test1() {
31   void *data = 0;
32   my_malloc1(&data, 4); // expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}}
33 }
34 
35 static void test11() {
36   void *data = 0;
37   my_malloc1(&data, 4);
38   my_free1(data);
39 }
40 
41 static void testUniqueingByallocationSiteInTopLevelFunction() {
42   void *data = my_malloc2(1, 4);
43   data = 0;
44   int x = 5;// expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}}
45   data = my_malloc2(1, 4);// expected-warning {{Memory is never released; potential leak of memory pointed to by 'data'}}
46 }
47 
48 static void test3() {
49   void *data = my_malloc2(1, 4);
50   free(data);
51   data = my_malloc2(1, 4);
52   free(data);
53 }
54 
55 int test4() {
56   int *data = (int*)my_malloc2(1, 4);
57   my_free1(data);
58   data = (int *)my_malloc2(1, 4);
59   my_free1(data);
60   return *data; // expected-warning {{Use of memory after it is freed}}
61 }
62 
63 void test6() {
64   int *data = (int *)my_malloc2(1, 4);
65   my_free1((int*)data);
66   my_free1((int*)data); // expected-warning{{Use of memory after it is freed}}
67 }
68 
69 // TODO: We should warn here.
70 void test5() {
71   int *data;
72   my_free1((int*)data);
73 }
74 
75 static char *reshape(char *in) {
76     return 0;
77 }
78 
79 void testThatRemoveDeadBindingsRunBeforeEachCall() {
80     char *v = malloc(12);
81     v = reshape(v);
82     v = reshape(v);// expected-warning {{Memory is never released; potential leak of memory pointed to by 'v'}}
83 }
84 
85 // Test that we keep processing after 'return;'
86 void fooWithEmptyReturn(int x) {
87   if (x)
88     return;
89   x++;
90   return;
91 }
92 
93 int uafAndCallsFooWithEmptyReturn() {
94   int *x = (int*)malloc(12);
95   free(x);
96   fooWithEmptyReturn(12);
97   return *x; // expected-warning {{Use of memory after it is freed}}
98 }
99