1f4a2713aSLionel Sambuc // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s
2f4a2713aSLionel Sambuc
3f4a2713aSLionel Sambuc #include "Inputs/system-header-simulator.h"
4f4a2713aSLionel Sambuc
5f4a2713aSLionel Sambuc void clang_analyzer_eval(int);
6f4a2713aSLionel Sambuc
7f4a2713aSLionel Sambuc typedef __typeof(sizeof(int)) size_t;
8f4a2713aSLionel Sambuc void *malloc(size_t);
9f4a2713aSLionel Sambuc void *valloc(size_t);
10f4a2713aSLionel Sambuc void free(void *);
11f4a2713aSLionel Sambuc void *realloc(void *ptr, size_t size);
12f4a2713aSLionel Sambuc void *reallocf(void *ptr, size_t size);
13f4a2713aSLionel Sambuc void *calloc(size_t nmemb, size_t size);
14f4a2713aSLionel Sambuc char *strdup(const char *s);
15f4a2713aSLionel Sambuc char *strndup(const char *s, size_t n);
16f4a2713aSLionel Sambuc int memcmp(const void *s1, const void *s2, size_t n);
17f4a2713aSLionel Sambuc
18f4a2713aSLionel Sambuc void myfoo(int *p);
19f4a2713aSLionel Sambuc void myfooint(int p);
20f4a2713aSLionel Sambuc char *fooRetPtr();
21f4a2713aSLionel Sambuc
f1()22f4a2713aSLionel Sambuc void f1() {
23f4a2713aSLionel Sambuc int *p = malloc(12);
24f4a2713aSLionel Sambuc return; // expected-warning{{Potential leak of memory pointed to by 'p'}}
25f4a2713aSLionel Sambuc }
26f4a2713aSLionel Sambuc
f2()27f4a2713aSLionel Sambuc void f2() {
28f4a2713aSLionel Sambuc int *p = malloc(12);
29f4a2713aSLionel Sambuc free(p);
30f4a2713aSLionel Sambuc free(p); // expected-warning{{Attempt to free released memory}}
31f4a2713aSLionel Sambuc }
32f4a2713aSLionel Sambuc
f2_realloc_0()33f4a2713aSLionel Sambuc void f2_realloc_0() {
34f4a2713aSLionel Sambuc int *p = malloc(12);
35f4a2713aSLionel Sambuc realloc(p,0);
36f4a2713aSLionel Sambuc realloc(p,0); // expected-warning{{Attempt to free released memory}}
37f4a2713aSLionel Sambuc }
38f4a2713aSLionel Sambuc
f2_realloc_1()39f4a2713aSLionel Sambuc void f2_realloc_1() {
40f4a2713aSLionel Sambuc int *p = malloc(12);
41f4a2713aSLionel Sambuc int *q = realloc(p,0); // no-warning
42f4a2713aSLionel Sambuc }
43f4a2713aSLionel Sambuc
reallocNotNullPtr(unsigned sizeIn)44f4a2713aSLionel Sambuc void reallocNotNullPtr(unsigned sizeIn) {
45f4a2713aSLionel Sambuc unsigned size = 12;
46f4a2713aSLionel Sambuc char *p = (char*)malloc(size);
47f4a2713aSLionel Sambuc if (p) {
48f4a2713aSLionel Sambuc char *q = (char*)realloc(p, sizeIn);
49f4a2713aSLionel Sambuc char x = *q; // expected-warning {{Potential leak of memory pointed to by 'q'}}
50f4a2713aSLionel Sambuc }
51f4a2713aSLionel Sambuc }
52f4a2713aSLionel Sambuc
realloctest1()53f4a2713aSLionel Sambuc int *realloctest1() {
54f4a2713aSLionel Sambuc int *q = malloc(12);
55f4a2713aSLionel Sambuc q = realloc(q, 20);
56f4a2713aSLionel Sambuc return q; // no warning - returning the allocated value
57f4a2713aSLionel Sambuc }
58f4a2713aSLionel Sambuc
59f4a2713aSLionel Sambuc // p should be freed if realloc fails.
reallocFails()60f4a2713aSLionel Sambuc void reallocFails() {
61f4a2713aSLionel Sambuc char *p = malloc(12);
62f4a2713aSLionel Sambuc char *r = realloc(p, 12+1);
63f4a2713aSLionel Sambuc if (!r) {
64f4a2713aSLionel Sambuc free(p);
65f4a2713aSLionel Sambuc } else {
66f4a2713aSLionel Sambuc free(r);
67f4a2713aSLionel Sambuc }
68f4a2713aSLionel Sambuc }
69f4a2713aSLionel Sambuc
reallocSizeZero1()70f4a2713aSLionel Sambuc void reallocSizeZero1() {
71f4a2713aSLionel Sambuc char *p = malloc(12);
72f4a2713aSLionel Sambuc char *r = realloc(p, 0);
73f4a2713aSLionel Sambuc if (!r) {
74f4a2713aSLionel Sambuc free(p); // expected-warning {{Attempt to free released memory}}
75f4a2713aSLionel Sambuc } else {
76f4a2713aSLionel Sambuc free(r);
77f4a2713aSLionel Sambuc }
78f4a2713aSLionel Sambuc }
79f4a2713aSLionel Sambuc
reallocSizeZero2()80f4a2713aSLionel Sambuc void reallocSizeZero2() {
81f4a2713aSLionel Sambuc char *p = malloc(12);
82f4a2713aSLionel Sambuc char *r = realloc(p, 0);
83f4a2713aSLionel Sambuc if (!r) {
84f4a2713aSLionel Sambuc free(p); // expected-warning {{Attempt to free released memory}}
85f4a2713aSLionel Sambuc } else {
86f4a2713aSLionel Sambuc free(r);
87f4a2713aSLionel Sambuc }
88f4a2713aSLionel Sambuc free(p); // expected-warning {{Attempt to free released memory}}
89f4a2713aSLionel Sambuc }
90f4a2713aSLionel Sambuc
reallocSizeZero3()91f4a2713aSLionel Sambuc void reallocSizeZero3() {
92f4a2713aSLionel Sambuc char *p = malloc(12);
93f4a2713aSLionel Sambuc char *r = realloc(p, 0);
94f4a2713aSLionel Sambuc free(r);
95f4a2713aSLionel Sambuc }
96f4a2713aSLionel Sambuc
reallocSizeZero4()97f4a2713aSLionel Sambuc void reallocSizeZero4() {
98f4a2713aSLionel Sambuc char *r = realloc(0, 0);
99f4a2713aSLionel Sambuc free(r);
100f4a2713aSLionel Sambuc }
101f4a2713aSLionel Sambuc
reallocSizeZero5()102f4a2713aSLionel Sambuc void reallocSizeZero5() {
103f4a2713aSLionel Sambuc char *r = realloc(0, 0);
104f4a2713aSLionel Sambuc }
105f4a2713aSLionel Sambuc
reallocPtrZero1()106f4a2713aSLionel Sambuc void reallocPtrZero1() {
107f4a2713aSLionel Sambuc char *r = realloc(0, 12);
108f4a2713aSLionel Sambuc } // expected-warning {{Potential leak of memory pointed to by 'r'}}
109f4a2713aSLionel Sambuc
reallocPtrZero2()110f4a2713aSLionel Sambuc void reallocPtrZero2() {
111f4a2713aSLionel Sambuc char *r = realloc(0, 12);
112f4a2713aSLionel Sambuc if (r)
113f4a2713aSLionel Sambuc free(r);
114f4a2713aSLionel Sambuc }
115f4a2713aSLionel Sambuc
reallocPtrZero3()116f4a2713aSLionel Sambuc void reallocPtrZero3() {
117f4a2713aSLionel Sambuc char *r = realloc(0, 12);
118f4a2713aSLionel Sambuc free(r);
119f4a2713aSLionel Sambuc }
120f4a2713aSLionel Sambuc
reallocRadar6337483_1()121f4a2713aSLionel Sambuc void reallocRadar6337483_1() {
122f4a2713aSLionel Sambuc char *buf = malloc(100);
123f4a2713aSLionel Sambuc buf = (char*)realloc(buf, 0x1000000);
124f4a2713aSLionel Sambuc if (!buf) {
125f4a2713aSLionel Sambuc return;// expected-warning {{Potential leak of memory pointed to by}}
126f4a2713aSLionel Sambuc }
127f4a2713aSLionel Sambuc free(buf);
128f4a2713aSLionel Sambuc }
129f4a2713aSLionel Sambuc
reallocRadar6337483_2()130f4a2713aSLionel Sambuc void reallocRadar6337483_2() {
131f4a2713aSLionel Sambuc char *buf = malloc(100);
132f4a2713aSLionel Sambuc char *buf2 = (char*)realloc(buf, 0x1000000);
133f4a2713aSLionel Sambuc if (!buf2) {
134f4a2713aSLionel Sambuc ;
135f4a2713aSLionel Sambuc } else {
136f4a2713aSLionel Sambuc free(buf2);
137f4a2713aSLionel Sambuc }
138f4a2713aSLionel Sambuc } // expected-warning {{Potential leak of memory pointed to by}}
139f4a2713aSLionel Sambuc
reallocRadar6337483_3()140f4a2713aSLionel Sambuc void reallocRadar6337483_3() {
141f4a2713aSLionel Sambuc char * buf = malloc(100);
142f4a2713aSLionel Sambuc char * tmp;
143f4a2713aSLionel Sambuc tmp = (char*)realloc(buf, 0x1000000);
144f4a2713aSLionel Sambuc if (!tmp) {
145f4a2713aSLionel Sambuc free(buf);
146f4a2713aSLionel Sambuc return;
147f4a2713aSLionel Sambuc }
148f4a2713aSLionel Sambuc buf = tmp;
149f4a2713aSLionel Sambuc free(buf);
150f4a2713aSLionel Sambuc }
151f4a2713aSLionel Sambuc
reallocRadar6337483_4()152f4a2713aSLionel Sambuc void reallocRadar6337483_4() {
153f4a2713aSLionel Sambuc char *buf = malloc(100);
154f4a2713aSLionel Sambuc char *buf2 = (char*)realloc(buf, 0x1000000);
155f4a2713aSLionel Sambuc if (!buf2) {
156f4a2713aSLionel Sambuc return; // expected-warning {{Potential leak of memory pointed to by}}
157f4a2713aSLionel Sambuc } else {
158f4a2713aSLionel Sambuc free(buf2);
159f4a2713aSLionel Sambuc }
160f4a2713aSLionel Sambuc }
161f4a2713aSLionel Sambuc
reallocfTest1()162f4a2713aSLionel Sambuc int *reallocfTest1() {
163f4a2713aSLionel Sambuc int *q = malloc(12);
164f4a2713aSLionel Sambuc q = reallocf(q, 20);
165f4a2713aSLionel Sambuc return q; // no warning - returning the allocated value
166f4a2713aSLionel Sambuc }
167f4a2713aSLionel Sambuc
reallocfRadar6337483_4()168f4a2713aSLionel Sambuc void reallocfRadar6337483_4() {
169f4a2713aSLionel Sambuc char *buf = malloc(100);
170f4a2713aSLionel Sambuc char *buf2 = (char*)reallocf(buf, 0x1000000);
171f4a2713aSLionel Sambuc if (!buf2) {
172f4a2713aSLionel Sambuc return; // no warning - reallocf frees even on failure
173f4a2713aSLionel Sambuc } else {
174f4a2713aSLionel Sambuc free(buf2);
175f4a2713aSLionel Sambuc }
176f4a2713aSLionel Sambuc }
177f4a2713aSLionel Sambuc
reallocfRadar6337483_3()178f4a2713aSLionel Sambuc void reallocfRadar6337483_3() {
179f4a2713aSLionel Sambuc char * buf = malloc(100);
180f4a2713aSLionel Sambuc char * tmp;
181f4a2713aSLionel Sambuc tmp = (char*)reallocf(buf, 0x1000000);
182f4a2713aSLionel Sambuc if (!tmp) {
183f4a2713aSLionel Sambuc free(buf); // expected-warning {{Attempt to free released memory}}
184f4a2713aSLionel Sambuc return;
185f4a2713aSLionel Sambuc }
186f4a2713aSLionel Sambuc buf = tmp;
187f4a2713aSLionel Sambuc free(buf);
188f4a2713aSLionel Sambuc }
189f4a2713aSLionel Sambuc
reallocfPtrZero1()190f4a2713aSLionel Sambuc void reallocfPtrZero1() {
191f4a2713aSLionel Sambuc char *r = reallocf(0, 12);
192f4a2713aSLionel Sambuc } // expected-warning {{Potential leak of memory pointed to by}}
193f4a2713aSLionel Sambuc
194f4a2713aSLionel Sambuc
195f4a2713aSLionel Sambuc // This case tests that storing malloc'ed memory to a static variable which is
196f4a2713aSLionel Sambuc // then returned is not leaked. In the absence of known contracts for functions
197f4a2713aSLionel Sambuc // or inter-procedural analysis, this is a conservative answer.
f3()198f4a2713aSLionel Sambuc int *f3() {
199f4a2713aSLionel Sambuc static int *p = 0;
200f4a2713aSLionel Sambuc p = malloc(12);
201f4a2713aSLionel Sambuc return p; // no-warning
202f4a2713aSLionel Sambuc }
203f4a2713aSLionel Sambuc
204f4a2713aSLionel Sambuc // This case tests that storing malloc'ed memory to a static global variable
205f4a2713aSLionel Sambuc // which is then returned is not leaked. In the absence of known contracts for
206f4a2713aSLionel Sambuc // functions or inter-procedural analysis, this is a conservative answer.
207f4a2713aSLionel Sambuc static int *p_f4 = 0;
f4()208f4a2713aSLionel Sambuc int *f4() {
209f4a2713aSLionel Sambuc p_f4 = malloc(12);
210f4a2713aSLionel Sambuc return p_f4; // no-warning
211f4a2713aSLionel Sambuc }
212f4a2713aSLionel Sambuc
f5()213f4a2713aSLionel Sambuc int *f5() {
214f4a2713aSLionel Sambuc int *q = malloc(12);
215f4a2713aSLionel Sambuc q = realloc(q, 20);
216f4a2713aSLionel Sambuc return q; // no-warning
217f4a2713aSLionel Sambuc }
218f4a2713aSLionel Sambuc
f6()219f4a2713aSLionel Sambuc void f6() {
220f4a2713aSLionel Sambuc int *p = malloc(12);
221f4a2713aSLionel Sambuc if (!p)
222f4a2713aSLionel Sambuc return; // no-warning
223f4a2713aSLionel Sambuc else
224f4a2713aSLionel Sambuc free(p);
225f4a2713aSLionel Sambuc }
226f4a2713aSLionel Sambuc
f6_realloc()227f4a2713aSLionel Sambuc void f6_realloc() {
228f4a2713aSLionel Sambuc int *p = malloc(12);
229f4a2713aSLionel Sambuc if (!p)
230f4a2713aSLionel Sambuc return; // no-warning
231f4a2713aSLionel Sambuc else
232f4a2713aSLionel Sambuc realloc(p,0);
233f4a2713aSLionel Sambuc }
234f4a2713aSLionel Sambuc
235f4a2713aSLionel Sambuc
236f4a2713aSLionel Sambuc char *doit2();
pr6069()237f4a2713aSLionel Sambuc void pr6069() {
238f4a2713aSLionel Sambuc char *buf = doit2();
239f4a2713aSLionel Sambuc free(buf);
240f4a2713aSLionel Sambuc }
241f4a2713aSLionel Sambuc
pr6293()242f4a2713aSLionel Sambuc void pr6293() {
243f4a2713aSLionel Sambuc free(0);
244f4a2713aSLionel Sambuc }
245f4a2713aSLionel Sambuc
f7()246f4a2713aSLionel Sambuc void f7() {
247f4a2713aSLionel Sambuc char *x = (char*) malloc(4);
248f4a2713aSLionel Sambuc free(x);
249f4a2713aSLionel Sambuc x[0] = 'a'; // expected-warning{{Use of memory after it is freed}}
250f4a2713aSLionel Sambuc }
251f4a2713aSLionel Sambuc
f8()252f4a2713aSLionel Sambuc void f8() {
253f4a2713aSLionel Sambuc char *x = (char*) malloc(4);
254f4a2713aSLionel Sambuc free(x);
255f4a2713aSLionel Sambuc char *y = strndup(x, 4); // expected-warning{{Use of memory after it is freed}}
256f4a2713aSLionel Sambuc }
257f4a2713aSLionel Sambuc
f7_realloc()258f4a2713aSLionel Sambuc void f7_realloc() {
259f4a2713aSLionel Sambuc char *x = (char*) malloc(4);
260f4a2713aSLionel Sambuc realloc(x,0);
261f4a2713aSLionel Sambuc x[0] = 'a'; // expected-warning{{Use of memory after it is freed}}
262f4a2713aSLionel Sambuc }
263f4a2713aSLionel Sambuc
PR6123()264f4a2713aSLionel Sambuc void PR6123() {
265f4a2713aSLionel Sambuc int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
266f4a2713aSLionel Sambuc }
267f4a2713aSLionel Sambuc
PR7217()268f4a2713aSLionel Sambuc void PR7217() {
269f4a2713aSLionel Sambuc int *buf = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
270f4a2713aSLionel Sambuc buf[1] = 'c'; // not crash
271f4a2713aSLionel Sambuc }
272f4a2713aSLionel Sambuc
cast_emtpy_struct()273*0a6a1f1dSLionel Sambuc void cast_emtpy_struct() {
274*0a6a1f1dSLionel Sambuc struct st {
275*0a6a1f1dSLionel Sambuc };
276*0a6a1f1dSLionel Sambuc
277*0a6a1f1dSLionel Sambuc struct st *s = malloc(sizeof(struct st)); // no-warning
278*0a6a1f1dSLionel Sambuc free(s);
279*0a6a1f1dSLionel Sambuc }
280*0a6a1f1dSLionel Sambuc
cast_struct_1()281*0a6a1f1dSLionel Sambuc void cast_struct_1() {
282*0a6a1f1dSLionel Sambuc struct st {
283*0a6a1f1dSLionel Sambuc int i[100];
284*0a6a1f1dSLionel Sambuc char j[];
285*0a6a1f1dSLionel Sambuc };
286*0a6a1f1dSLionel Sambuc
287*0a6a1f1dSLionel Sambuc struct st *s = malloc(sizeof(struct st)); // no-warning
288*0a6a1f1dSLionel Sambuc free(s);
289*0a6a1f1dSLionel Sambuc }
290*0a6a1f1dSLionel Sambuc
cast_struct_2()291*0a6a1f1dSLionel Sambuc void cast_struct_2() {
292*0a6a1f1dSLionel Sambuc struct st {
293*0a6a1f1dSLionel Sambuc int i[100];
294*0a6a1f1dSLionel Sambuc char j[0];
295*0a6a1f1dSLionel Sambuc };
296*0a6a1f1dSLionel Sambuc
297*0a6a1f1dSLionel Sambuc struct st *s = malloc(sizeof(struct st)); // no-warning
298*0a6a1f1dSLionel Sambuc free(s);
299*0a6a1f1dSLionel Sambuc }
300*0a6a1f1dSLionel Sambuc
cast_struct_3()301*0a6a1f1dSLionel Sambuc void cast_struct_3() {
302*0a6a1f1dSLionel Sambuc struct st {
303*0a6a1f1dSLionel Sambuc int i[100];
304*0a6a1f1dSLionel Sambuc char j[1];
305*0a6a1f1dSLionel Sambuc };
306*0a6a1f1dSLionel Sambuc
307*0a6a1f1dSLionel Sambuc struct st *s = malloc(sizeof(struct st)); // no-warning
308*0a6a1f1dSLionel Sambuc free(s);
309*0a6a1f1dSLionel Sambuc }
310*0a6a1f1dSLionel Sambuc
cast_struct_4()311*0a6a1f1dSLionel Sambuc void cast_struct_4() {
312*0a6a1f1dSLionel Sambuc struct st {
313*0a6a1f1dSLionel Sambuc int i[100];
314*0a6a1f1dSLionel Sambuc char j[2];
315*0a6a1f1dSLionel Sambuc };
316*0a6a1f1dSLionel Sambuc
317*0a6a1f1dSLionel Sambuc struct st *s = malloc(sizeof(struct st)); // no-warning
318*0a6a1f1dSLionel Sambuc free(s);
319*0a6a1f1dSLionel Sambuc }
320*0a6a1f1dSLionel Sambuc
cast_struct_5()321*0a6a1f1dSLionel Sambuc void cast_struct_5() {
322*0a6a1f1dSLionel Sambuc struct st {
323*0a6a1f1dSLionel Sambuc char i[200];
324*0a6a1f1dSLionel Sambuc char j[1];
325*0a6a1f1dSLionel Sambuc };
326*0a6a1f1dSLionel Sambuc
327*0a6a1f1dSLionel Sambuc struct st *s = malloc(sizeof(struct st) - sizeof(char)); // no-warning
328*0a6a1f1dSLionel Sambuc free(s);
329*0a6a1f1dSLionel Sambuc }
330*0a6a1f1dSLionel Sambuc
cast_struct_warn_1()331*0a6a1f1dSLionel Sambuc void cast_struct_warn_1() {
332*0a6a1f1dSLionel Sambuc struct st {
333*0a6a1f1dSLionel Sambuc int i[100];
334*0a6a1f1dSLionel Sambuc char j[2];
335*0a6a1f1dSLionel Sambuc };
336*0a6a1f1dSLionel Sambuc
337*0a6a1f1dSLionel Sambuc struct st *s = malloc(sizeof(struct st) + 2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
338*0a6a1f1dSLionel Sambuc free(s);
339*0a6a1f1dSLionel Sambuc }
340*0a6a1f1dSLionel Sambuc
cast_struct_warn_2()341*0a6a1f1dSLionel Sambuc void cast_struct_warn_2() {
342*0a6a1f1dSLionel Sambuc struct st {
343*0a6a1f1dSLionel Sambuc int i[100];
344*0a6a1f1dSLionel Sambuc char j[2];
345*0a6a1f1dSLionel Sambuc };
346*0a6a1f1dSLionel Sambuc
347*0a6a1f1dSLionel Sambuc struct st *s = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
348*0a6a1f1dSLionel Sambuc free(s);
349*0a6a1f1dSLionel Sambuc }
350*0a6a1f1dSLionel Sambuc
cast_struct_flex_array_1()351*0a6a1f1dSLionel Sambuc void cast_struct_flex_array_1() {
352*0a6a1f1dSLionel Sambuc struct st {
353*0a6a1f1dSLionel Sambuc int i[100];
354*0a6a1f1dSLionel Sambuc char j[];
355*0a6a1f1dSLionel Sambuc };
356*0a6a1f1dSLionel Sambuc
357*0a6a1f1dSLionel Sambuc struct st *s = malloc(sizeof(struct st) + 3); // no-warning
358*0a6a1f1dSLionel Sambuc free(s);
359*0a6a1f1dSLionel Sambuc }
360*0a6a1f1dSLionel Sambuc
cast_struct_flex_array_2()361*0a6a1f1dSLionel Sambuc void cast_struct_flex_array_2() {
362*0a6a1f1dSLionel Sambuc struct st {
363*0a6a1f1dSLionel Sambuc int i[100];
364*0a6a1f1dSLionel Sambuc char j[0];
365*0a6a1f1dSLionel Sambuc };
366*0a6a1f1dSLionel Sambuc
367*0a6a1f1dSLionel Sambuc struct st *s = malloc(sizeof(struct st) + 3); // no-warning
368*0a6a1f1dSLionel Sambuc free(s);
369*0a6a1f1dSLionel Sambuc }
370*0a6a1f1dSLionel Sambuc
cast_struct_flex_array_3()371*0a6a1f1dSLionel Sambuc void cast_struct_flex_array_3() {
372*0a6a1f1dSLionel Sambuc struct st {
373*0a6a1f1dSLionel Sambuc int i[100];
374*0a6a1f1dSLionel Sambuc char j[1];
375*0a6a1f1dSLionel Sambuc };
376*0a6a1f1dSLionel Sambuc
377*0a6a1f1dSLionel Sambuc struct st *s = malloc(sizeof(struct st) + 3); // no-warning
378*0a6a1f1dSLionel Sambuc free(s);
379*0a6a1f1dSLionel Sambuc }
380*0a6a1f1dSLionel Sambuc
cast_struct_flex_array_4()381*0a6a1f1dSLionel Sambuc void cast_struct_flex_array_4() {
382*0a6a1f1dSLionel Sambuc struct foo {
383*0a6a1f1dSLionel Sambuc char f[32];
384*0a6a1f1dSLionel Sambuc };
385*0a6a1f1dSLionel Sambuc struct st {
386*0a6a1f1dSLionel Sambuc char i[100];
387*0a6a1f1dSLionel Sambuc struct foo data[];
388*0a6a1f1dSLionel Sambuc };
389*0a6a1f1dSLionel Sambuc
390*0a6a1f1dSLionel Sambuc struct st *s = malloc(sizeof(struct st) + 3 * sizeof(struct foo)); // no-warning
391*0a6a1f1dSLionel Sambuc free(s);
392*0a6a1f1dSLionel Sambuc }
393*0a6a1f1dSLionel Sambuc
cast_struct_flex_array_5()394*0a6a1f1dSLionel Sambuc void cast_struct_flex_array_5() {
395*0a6a1f1dSLionel Sambuc struct foo {
396*0a6a1f1dSLionel Sambuc char f[32];
397*0a6a1f1dSLionel Sambuc };
398*0a6a1f1dSLionel Sambuc struct st {
399*0a6a1f1dSLionel Sambuc char i[100];
400*0a6a1f1dSLionel Sambuc struct foo data[0];
401*0a6a1f1dSLionel Sambuc };
402*0a6a1f1dSLionel Sambuc
403*0a6a1f1dSLionel Sambuc struct st *s = malloc(sizeof(struct st) + 3 * sizeof(struct foo)); // no-warning
404*0a6a1f1dSLionel Sambuc free(s);
405*0a6a1f1dSLionel Sambuc }
406*0a6a1f1dSLionel Sambuc
cast_struct_flex_array_6()407*0a6a1f1dSLionel Sambuc void cast_struct_flex_array_6() {
408*0a6a1f1dSLionel Sambuc struct foo {
409*0a6a1f1dSLionel Sambuc char f[32];
410*0a6a1f1dSLionel Sambuc };
411*0a6a1f1dSLionel Sambuc struct st {
412*0a6a1f1dSLionel Sambuc char i[100];
413*0a6a1f1dSLionel Sambuc struct foo data[1];
414*0a6a1f1dSLionel Sambuc };
415*0a6a1f1dSLionel Sambuc
416*0a6a1f1dSLionel Sambuc struct st *s = malloc(sizeof(struct st) + 3 * sizeof(struct foo)); // no-warning
417*0a6a1f1dSLionel Sambuc free(s);
418*0a6a1f1dSLionel Sambuc }
419*0a6a1f1dSLionel Sambuc
cast_struct_flex_array_warn_1()420*0a6a1f1dSLionel Sambuc void cast_struct_flex_array_warn_1() {
421*0a6a1f1dSLionel Sambuc struct foo {
422*0a6a1f1dSLionel Sambuc char f[32];
423*0a6a1f1dSLionel Sambuc };
424*0a6a1f1dSLionel Sambuc struct st {
425*0a6a1f1dSLionel Sambuc char i[100];
426*0a6a1f1dSLionel Sambuc struct foo data[];
427*0a6a1f1dSLionel Sambuc };
428*0a6a1f1dSLionel Sambuc
429*0a6a1f1dSLionel Sambuc struct st *s = malloc(3 * sizeof(struct st) + 3 * sizeof(struct foo)); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
430*0a6a1f1dSLionel Sambuc free(s);
431*0a6a1f1dSLionel Sambuc }
432*0a6a1f1dSLionel Sambuc
cast_struct_flex_array_warn_2()433*0a6a1f1dSLionel Sambuc void cast_struct_flex_array_warn_2() {
434*0a6a1f1dSLionel Sambuc struct foo {
435*0a6a1f1dSLionel Sambuc char f[32];
436*0a6a1f1dSLionel Sambuc };
437*0a6a1f1dSLionel Sambuc struct st {
438*0a6a1f1dSLionel Sambuc char i[100];
439*0a6a1f1dSLionel Sambuc struct foo data[0];
440*0a6a1f1dSLionel Sambuc };
441*0a6a1f1dSLionel Sambuc
442*0a6a1f1dSLionel Sambuc struct st *s = malloc(3 * sizeof(struct st) + 3 * sizeof(struct foo)); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
443*0a6a1f1dSLionel Sambuc free(s);
444*0a6a1f1dSLionel Sambuc }
445*0a6a1f1dSLionel Sambuc
cast_struct_flex_array_warn_3()446*0a6a1f1dSLionel Sambuc void cast_struct_flex_array_warn_3() {
447*0a6a1f1dSLionel Sambuc struct foo {
448*0a6a1f1dSLionel Sambuc char f[32];
449*0a6a1f1dSLionel Sambuc };
450*0a6a1f1dSLionel Sambuc struct st {
451*0a6a1f1dSLionel Sambuc char i[100];
452*0a6a1f1dSLionel Sambuc struct foo data[1];
453*0a6a1f1dSLionel Sambuc };
454*0a6a1f1dSLionel Sambuc
455*0a6a1f1dSLionel Sambuc struct st *s = malloc(3 * sizeof(struct st) + 3 * sizeof(struct foo)); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
456*0a6a1f1dSLionel Sambuc free(s);
457*0a6a1f1dSLionel Sambuc }
458*0a6a1f1dSLionel Sambuc
cast_struct_flex_array_warn_4()459*0a6a1f1dSLionel Sambuc void cast_struct_flex_array_warn_4() {
460*0a6a1f1dSLionel Sambuc struct st {
461*0a6a1f1dSLionel Sambuc int i[100];
462*0a6a1f1dSLionel Sambuc int j[];
463*0a6a1f1dSLionel Sambuc };
464*0a6a1f1dSLionel Sambuc
465*0a6a1f1dSLionel Sambuc struct st *s = malloc(sizeof(struct st) + 3); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
466*0a6a1f1dSLionel Sambuc free(s);
467*0a6a1f1dSLionel Sambuc }
468*0a6a1f1dSLionel Sambuc
cast_struct_flex_array_warn_5()469*0a6a1f1dSLionel Sambuc void cast_struct_flex_array_warn_5() {
470*0a6a1f1dSLionel Sambuc struct st {
471*0a6a1f1dSLionel Sambuc int i[100];
472*0a6a1f1dSLionel Sambuc int j[0];
473*0a6a1f1dSLionel Sambuc };
474*0a6a1f1dSLionel Sambuc
475*0a6a1f1dSLionel Sambuc struct st *s = malloc(sizeof(struct st) + 3); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
476*0a6a1f1dSLionel Sambuc free(s);
477*0a6a1f1dSLionel Sambuc }
478*0a6a1f1dSLionel Sambuc
cast_struct_flex_array_warn_6()479*0a6a1f1dSLionel Sambuc void cast_struct_flex_array_warn_6() {
480*0a6a1f1dSLionel Sambuc struct st {
481*0a6a1f1dSLionel Sambuc int i[100];
482*0a6a1f1dSLionel Sambuc int j[1];
483*0a6a1f1dSLionel Sambuc };
484*0a6a1f1dSLionel Sambuc
485*0a6a1f1dSLionel Sambuc struct st *s = malloc(sizeof(struct st) + 3); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
486*0a6a1f1dSLionel Sambuc free(s);
487*0a6a1f1dSLionel Sambuc }
488*0a6a1f1dSLionel Sambuc
mallocCastToVoid()489f4a2713aSLionel Sambuc void mallocCastToVoid() {
490f4a2713aSLionel Sambuc void *p = malloc(2);
491f4a2713aSLionel Sambuc const void *cp = p; // not crash
492f4a2713aSLionel Sambuc free(p);
493f4a2713aSLionel Sambuc }
494f4a2713aSLionel Sambuc
mallocCastToFP()495f4a2713aSLionel Sambuc void mallocCastToFP() {
496f4a2713aSLionel Sambuc void *p = malloc(2);
497f4a2713aSLionel Sambuc void (*fp)() = p; // not crash
498f4a2713aSLionel Sambuc free(p);
499f4a2713aSLionel Sambuc }
500f4a2713aSLionel Sambuc
501f4a2713aSLionel Sambuc // This tests that malloc() buffers are undefined by default
mallocGarbage()502f4a2713aSLionel Sambuc char mallocGarbage () {
503f4a2713aSLionel Sambuc char *buf = malloc(2);
504f4a2713aSLionel Sambuc char result = buf[1]; // expected-warning{{undefined}}
505f4a2713aSLionel Sambuc free(buf);
506f4a2713aSLionel Sambuc return result;
507f4a2713aSLionel Sambuc }
508f4a2713aSLionel Sambuc
509f4a2713aSLionel Sambuc // This tests that calloc() buffers need to be freed
callocNoFree()510f4a2713aSLionel Sambuc void callocNoFree () {
511f4a2713aSLionel Sambuc char *buf = calloc(2,2);
512f4a2713aSLionel Sambuc return; // expected-warning{{Potential leak of memory pointed to by 'buf'}}
513f4a2713aSLionel Sambuc }
514f4a2713aSLionel Sambuc
515f4a2713aSLionel Sambuc // These test that calloc() buffers are zeroed by default
callocZeroesGood()516f4a2713aSLionel Sambuc char callocZeroesGood () {
517f4a2713aSLionel Sambuc char *buf = calloc(2,2);
518f4a2713aSLionel Sambuc char result = buf[3]; // no-warning
519f4a2713aSLionel Sambuc if (buf[1] == 0) {
520f4a2713aSLionel Sambuc free(buf);
521f4a2713aSLionel Sambuc }
522f4a2713aSLionel Sambuc return result; // no-warning
523f4a2713aSLionel Sambuc }
524f4a2713aSLionel Sambuc
callocZeroesBad()525f4a2713aSLionel Sambuc char callocZeroesBad () {
526f4a2713aSLionel Sambuc char *buf = calloc(2,2);
527f4a2713aSLionel Sambuc char result = buf[3]; // no-warning
528f4a2713aSLionel Sambuc if (buf[1] != 0) {
529f4a2713aSLionel Sambuc free(buf); // expected-warning{{never executed}}
530f4a2713aSLionel Sambuc }
531f4a2713aSLionel Sambuc return result; // expected-warning{{Potential leak of memory pointed to by 'buf'}}
532f4a2713aSLionel Sambuc }
533f4a2713aSLionel Sambuc
nullFree()534f4a2713aSLionel Sambuc void nullFree() {
535f4a2713aSLionel Sambuc int *p = 0;
536f4a2713aSLionel Sambuc free(p); // no warning - a nop
537f4a2713aSLionel Sambuc }
538f4a2713aSLionel Sambuc
paramFree(int * p)539f4a2713aSLionel Sambuc void paramFree(int *p) {
540f4a2713aSLionel Sambuc myfoo(p);
541f4a2713aSLionel Sambuc free(p); // no warning
542f4a2713aSLionel Sambuc myfoo(p); // expected-warning {{Use of memory after it is freed}}
543f4a2713aSLionel Sambuc }
544f4a2713aSLionel Sambuc
mallocEscapeRet()545f4a2713aSLionel Sambuc int* mallocEscapeRet() {
546f4a2713aSLionel Sambuc int *p = malloc(12);
547f4a2713aSLionel Sambuc return p; // no warning
548f4a2713aSLionel Sambuc }
549f4a2713aSLionel Sambuc
mallocEscapeFoo()550f4a2713aSLionel Sambuc void mallocEscapeFoo() {
551f4a2713aSLionel Sambuc int *p = malloc(12);
552f4a2713aSLionel Sambuc myfoo(p);
553f4a2713aSLionel Sambuc return; // no warning
554f4a2713aSLionel Sambuc }
555f4a2713aSLionel Sambuc
mallocEscapeFree()556f4a2713aSLionel Sambuc void mallocEscapeFree() {
557f4a2713aSLionel Sambuc int *p = malloc(12);
558f4a2713aSLionel Sambuc myfoo(p);
559f4a2713aSLionel Sambuc free(p);
560f4a2713aSLionel Sambuc }
561f4a2713aSLionel Sambuc
mallocEscapeFreeFree()562f4a2713aSLionel Sambuc void mallocEscapeFreeFree() {
563f4a2713aSLionel Sambuc int *p = malloc(12);
564f4a2713aSLionel Sambuc myfoo(p);
565f4a2713aSLionel Sambuc free(p);
566f4a2713aSLionel Sambuc free(p); // expected-warning{{Attempt to free released memory}}
567f4a2713aSLionel Sambuc }
568f4a2713aSLionel Sambuc
mallocEscapeFreeUse()569f4a2713aSLionel Sambuc void mallocEscapeFreeUse() {
570f4a2713aSLionel Sambuc int *p = malloc(12);
571f4a2713aSLionel Sambuc myfoo(p);
572f4a2713aSLionel Sambuc free(p);
573f4a2713aSLionel Sambuc myfoo(p); // expected-warning{{Use of memory after it is freed}}
574f4a2713aSLionel Sambuc }
575f4a2713aSLionel Sambuc
576f4a2713aSLionel Sambuc int *myalloc();
577f4a2713aSLionel Sambuc void myalloc2(int **p);
578f4a2713aSLionel Sambuc
mallocEscapeFreeCustomAlloc()579f4a2713aSLionel Sambuc void mallocEscapeFreeCustomAlloc() {
580f4a2713aSLionel Sambuc int *p = malloc(12);
581f4a2713aSLionel Sambuc myfoo(p);
582f4a2713aSLionel Sambuc free(p);
583f4a2713aSLionel Sambuc p = myalloc();
584f4a2713aSLionel Sambuc free(p); // no warning
585f4a2713aSLionel Sambuc }
586f4a2713aSLionel Sambuc
mallocEscapeFreeCustomAlloc2()587f4a2713aSLionel Sambuc void mallocEscapeFreeCustomAlloc2() {
588f4a2713aSLionel Sambuc int *p = malloc(12);
589f4a2713aSLionel Sambuc myfoo(p);
590f4a2713aSLionel Sambuc free(p);
591f4a2713aSLionel Sambuc myalloc2(&p);
592f4a2713aSLionel Sambuc free(p); // no warning
593f4a2713aSLionel Sambuc }
594f4a2713aSLionel Sambuc
mallocBindFreeUse()595f4a2713aSLionel Sambuc void mallocBindFreeUse() {
596f4a2713aSLionel Sambuc int *x = malloc(12);
597f4a2713aSLionel Sambuc int *y = x;
598f4a2713aSLionel Sambuc free(y);
599f4a2713aSLionel Sambuc myfoo(x); // expected-warning{{Use of memory after it is freed}}
600f4a2713aSLionel Sambuc }
601f4a2713aSLionel Sambuc
mallocEscapeMalloc()602f4a2713aSLionel Sambuc void mallocEscapeMalloc() {
603f4a2713aSLionel Sambuc int *p = malloc(12);
604f4a2713aSLionel Sambuc myfoo(p);
605f4a2713aSLionel Sambuc p = malloc(12);
606f4a2713aSLionel Sambuc } // expected-warning{{Potential leak of memory pointed to by}}
607f4a2713aSLionel Sambuc
mallocMalloc()608f4a2713aSLionel Sambuc void mallocMalloc() {
609f4a2713aSLionel Sambuc int *p = malloc(12);
610f4a2713aSLionel Sambuc p = malloc(12);
611f4a2713aSLionel Sambuc } // expected-warning {{Potential leak of memory pointed to by}}
612f4a2713aSLionel Sambuc
mallocFreeMalloc()613f4a2713aSLionel Sambuc void mallocFreeMalloc() {
614f4a2713aSLionel Sambuc int *p = malloc(12);
615f4a2713aSLionel Sambuc free(p);
616f4a2713aSLionel Sambuc p = malloc(12);
617f4a2713aSLionel Sambuc free(p);
618f4a2713aSLionel Sambuc }
619f4a2713aSLionel Sambuc
mallocFreeUse_params()620f4a2713aSLionel Sambuc void mallocFreeUse_params() {
621f4a2713aSLionel Sambuc int *p = malloc(12);
622f4a2713aSLionel Sambuc free(p);
623f4a2713aSLionel Sambuc myfoo(p); //expected-warning{{Use of memory after it is freed}}
624f4a2713aSLionel Sambuc }
625f4a2713aSLionel Sambuc
mallocFreeUse_params2()626f4a2713aSLionel Sambuc void mallocFreeUse_params2() {
627f4a2713aSLionel Sambuc int *p = malloc(12);
628f4a2713aSLionel Sambuc free(p);
629f4a2713aSLionel Sambuc myfooint(*p); //expected-warning{{Use of memory after it is freed}}
630f4a2713aSLionel Sambuc }
631f4a2713aSLionel Sambuc
mallocFailedOrNot()632f4a2713aSLionel Sambuc void mallocFailedOrNot() {
633f4a2713aSLionel Sambuc int *p = malloc(12);
634f4a2713aSLionel Sambuc if (!p)
635f4a2713aSLionel Sambuc free(p);
636f4a2713aSLionel Sambuc else
637f4a2713aSLionel Sambuc free(p);
638f4a2713aSLionel Sambuc }
639f4a2713aSLionel Sambuc
640f4a2713aSLionel Sambuc struct StructWithInt {
641f4a2713aSLionel Sambuc int g;
642f4a2713aSLionel Sambuc };
643f4a2713aSLionel Sambuc
mallocReturnFreed()644f4a2713aSLionel Sambuc int *mallocReturnFreed() {
645f4a2713aSLionel Sambuc int *p = malloc(12);
646f4a2713aSLionel Sambuc free(p);
647f4a2713aSLionel Sambuc return p; // expected-warning {{Use of memory after it is freed}}
648f4a2713aSLionel Sambuc }
649f4a2713aSLionel Sambuc
useAfterFreeStruct()650f4a2713aSLionel Sambuc int useAfterFreeStruct() {
651f4a2713aSLionel Sambuc struct StructWithInt *px= malloc(sizeof(struct StructWithInt));
652f4a2713aSLionel Sambuc px->g = 5;
653f4a2713aSLionel Sambuc free(px);
654f4a2713aSLionel Sambuc return px->g; // expected-warning {{Use of memory after it is freed}}
655f4a2713aSLionel Sambuc }
656f4a2713aSLionel Sambuc
657f4a2713aSLionel Sambuc void nonSymbolAsFirstArg(int *pp, struct StructWithInt *p);
658f4a2713aSLionel Sambuc
mallocEscapeFooNonSymbolArg()659f4a2713aSLionel Sambuc void mallocEscapeFooNonSymbolArg() {
660f4a2713aSLionel Sambuc struct StructWithInt *p = malloc(sizeof(struct StructWithInt));
661f4a2713aSLionel Sambuc nonSymbolAsFirstArg(&p->g, p);
662f4a2713aSLionel Sambuc return; // no warning
663f4a2713aSLionel Sambuc }
664f4a2713aSLionel Sambuc
mallocFailedOrNotLeak()665f4a2713aSLionel Sambuc void mallocFailedOrNotLeak() {
666f4a2713aSLionel Sambuc int *p = malloc(12);
667f4a2713aSLionel Sambuc if (p == 0)
668f4a2713aSLionel Sambuc return; // no warning
669f4a2713aSLionel Sambuc else
670f4a2713aSLionel Sambuc return; // expected-warning {{Potential leak of memory pointed to by}}
671f4a2713aSLionel Sambuc }
672f4a2713aSLionel Sambuc
mallocAssignment()673f4a2713aSLionel Sambuc void mallocAssignment() {
674f4a2713aSLionel Sambuc char *p = malloc(12);
675f4a2713aSLionel Sambuc p = fooRetPtr();
676f4a2713aSLionel Sambuc } // expected-warning {{leak}}
677f4a2713aSLionel Sambuc
vallocTest()678f4a2713aSLionel Sambuc int vallocTest() {
679f4a2713aSLionel Sambuc char *mem = valloc(12);
680f4a2713aSLionel Sambuc return 0; // expected-warning {{Potential leak of memory pointed to by}}
681f4a2713aSLionel Sambuc }
682f4a2713aSLionel Sambuc
vallocEscapeFreeUse()683f4a2713aSLionel Sambuc void vallocEscapeFreeUse() {
684f4a2713aSLionel Sambuc int *p = valloc(12);
685f4a2713aSLionel Sambuc myfoo(p);
686f4a2713aSLionel Sambuc free(p);
687f4a2713aSLionel Sambuc myfoo(p); // expected-warning{{Use of memory after it is freed}}
688f4a2713aSLionel Sambuc }
689f4a2713aSLionel Sambuc
690f4a2713aSLionel Sambuc int *Gl;
691f4a2713aSLionel Sambuc struct GlStTy {
692f4a2713aSLionel Sambuc int *x;
693f4a2713aSLionel Sambuc };
694f4a2713aSLionel Sambuc
695f4a2713aSLionel Sambuc struct GlStTy GlS = {0};
696f4a2713aSLionel Sambuc
GlobalFree()697f4a2713aSLionel Sambuc void GlobalFree() {
698f4a2713aSLionel Sambuc free(Gl);
699f4a2713aSLionel Sambuc }
700f4a2713aSLionel Sambuc
GlobalMalloc()701f4a2713aSLionel Sambuc void GlobalMalloc() {
702f4a2713aSLionel Sambuc Gl = malloc(12);
703f4a2713aSLionel Sambuc }
704f4a2713aSLionel Sambuc
GlobalStructMalloc()705f4a2713aSLionel Sambuc void GlobalStructMalloc() {
706f4a2713aSLionel Sambuc int *a = malloc(12);
707f4a2713aSLionel Sambuc GlS.x = a;
708f4a2713aSLionel Sambuc }
709f4a2713aSLionel Sambuc
GlobalStructMallocFree()710f4a2713aSLionel Sambuc void GlobalStructMallocFree() {
711f4a2713aSLionel Sambuc int *a = malloc(12);
712f4a2713aSLionel Sambuc GlS.x = a;
713f4a2713aSLionel Sambuc free(GlS.x);
714f4a2713aSLionel Sambuc }
715f4a2713aSLionel Sambuc
716f4a2713aSLionel Sambuc char *ArrayG[12];
717f4a2713aSLionel Sambuc
globalArrayTest()718f4a2713aSLionel Sambuc void globalArrayTest() {
719f4a2713aSLionel Sambuc char *p = (char*)malloc(12);
720f4a2713aSLionel Sambuc ArrayG[0] = p;
721f4a2713aSLionel Sambuc }
722f4a2713aSLionel Sambuc
723f4a2713aSLionel Sambuc // Make sure that we properly handle a pointer stored into a local struct/array.
724f4a2713aSLionel Sambuc typedef struct _StructWithPtr {
725f4a2713aSLionel Sambuc int *memP;
726f4a2713aSLionel Sambuc } StructWithPtr;
727f4a2713aSLionel Sambuc
728f4a2713aSLionel Sambuc static StructWithPtr arrOfStructs[10];
729f4a2713aSLionel Sambuc
testMalloc()730f4a2713aSLionel Sambuc void testMalloc() {
731f4a2713aSLionel Sambuc int *x = malloc(12);
732f4a2713aSLionel Sambuc StructWithPtr St;
733f4a2713aSLionel Sambuc St.memP = x;
734f4a2713aSLionel Sambuc arrOfStructs[0] = St; // no-warning
735f4a2713aSLionel Sambuc }
736f4a2713aSLionel Sambuc
testMalloc2()737f4a2713aSLionel Sambuc StructWithPtr testMalloc2() {
738f4a2713aSLionel Sambuc int *x = malloc(12);
739f4a2713aSLionel Sambuc StructWithPtr St;
740f4a2713aSLionel Sambuc St.memP = x;
741f4a2713aSLionel Sambuc return St; // no-warning
742f4a2713aSLionel Sambuc }
743f4a2713aSLionel Sambuc
testMalloc3()744f4a2713aSLionel Sambuc int *testMalloc3() {
745f4a2713aSLionel Sambuc int *x = malloc(12);
746f4a2713aSLionel Sambuc int *y = x;
747f4a2713aSLionel Sambuc return y; // no-warning
748f4a2713aSLionel Sambuc }
749f4a2713aSLionel Sambuc
testStructLeak()750f4a2713aSLionel Sambuc void testStructLeak() {
751f4a2713aSLionel Sambuc StructWithPtr St;
752f4a2713aSLionel Sambuc St.memP = malloc(12);
753f4a2713aSLionel Sambuc return; // expected-warning {{Potential leak of memory pointed to by 'St.memP'}}
754f4a2713aSLionel Sambuc }
755f4a2713aSLionel Sambuc
testElemRegion1()756f4a2713aSLionel Sambuc void testElemRegion1() {
757f4a2713aSLionel Sambuc char *x = (void*)malloc(2);
758f4a2713aSLionel Sambuc int *ix = (int*)x;
759f4a2713aSLionel Sambuc free(&(x[0]));
760f4a2713aSLionel Sambuc }
761f4a2713aSLionel Sambuc
testElemRegion2(int ** pp)762f4a2713aSLionel Sambuc void testElemRegion2(int **pp) {
763f4a2713aSLionel Sambuc int *p = malloc(12);
764f4a2713aSLionel Sambuc *pp = p;
765f4a2713aSLionel Sambuc free(pp[0]);
766f4a2713aSLionel Sambuc }
767f4a2713aSLionel Sambuc
testElemRegion3(int ** pp)768f4a2713aSLionel Sambuc void testElemRegion3(int **pp) {
769f4a2713aSLionel Sambuc int *p = malloc(12);
770f4a2713aSLionel Sambuc *pp = p;
771f4a2713aSLionel Sambuc free(*pp);
772f4a2713aSLionel Sambuc }
773f4a2713aSLionel Sambuc // Region escape testing.
774f4a2713aSLionel Sambuc
775f4a2713aSLionel Sambuc unsigned takePtrToPtr(int **p);
PassTheAddrOfAllocatedData(int f)776f4a2713aSLionel Sambuc void PassTheAddrOfAllocatedData(int f) {
777f4a2713aSLionel Sambuc int *p = malloc(12);
778f4a2713aSLionel Sambuc // We don't know what happens after the call. Should stop tracking here.
779f4a2713aSLionel Sambuc if (takePtrToPtr(&p))
780f4a2713aSLionel Sambuc f++;
781f4a2713aSLionel Sambuc free(p); // no warning
782f4a2713aSLionel Sambuc }
783f4a2713aSLionel Sambuc
784f4a2713aSLionel Sambuc struct X {
785f4a2713aSLionel Sambuc int *p;
786f4a2713aSLionel Sambuc };
787f4a2713aSLionel Sambuc unsigned takePtrToStruct(struct X *s);
foo2(int * g,int f)788f4a2713aSLionel Sambuc int ** foo2(int *g, int f) {
789f4a2713aSLionel Sambuc int *p = malloc(12);
790f4a2713aSLionel Sambuc struct X *px= malloc(sizeof(struct X));
791f4a2713aSLionel Sambuc px->p = p;
792f4a2713aSLionel Sambuc // We don't know what happens after this call. Should not track px nor p.
793f4a2713aSLionel Sambuc if (takePtrToStruct(px))
794f4a2713aSLionel Sambuc f++;
795f4a2713aSLionel Sambuc free(p);
796f4a2713aSLionel Sambuc return 0;
797f4a2713aSLionel Sambuc }
798f4a2713aSLionel Sambuc
RegInvalidationDetect1(struct X * s2)799f4a2713aSLionel Sambuc struct X* RegInvalidationDetect1(struct X *s2) {
800f4a2713aSLionel Sambuc struct X *px= malloc(sizeof(struct X));
801f4a2713aSLionel Sambuc px->p = 0;
802f4a2713aSLionel Sambuc px = s2;
803f4a2713aSLionel Sambuc return px; // expected-warning {{Potential leak of memory pointed to by}}
804f4a2713aSLionel Sambuc }
805f4a2713aSLionel Sambuc
RegInvalidationGiveUp1()806f4a2713aSLionel Sambuc struct X* RegInvalidationGiveUp1() {
807f4a2713aSLionel Sambuc int *p = malloc(12);
808f4a2713aSLionel Sambuc struct X *px= malloc(sizeof(struct X));
809f4a2713aSLionel Sambuc px->p = p;
810f4a2713aSLionel Sambuc return px;
811f4a2713aSLionel Sambuc }
812f4a2713aSLionel Sambuc
RegInvalidationDetect2(int ** pp)813f4a2713aSLionel Sambuc int **RegInvalidationDetect2(int **pp) {
814f4a2713aSLionel Sambuc int *p = malloc(12);
815f4a2713aSLionel Sambuc pp = &p;
816f4a2713aSLionel Sambuc pp++;
817f4a2713aSLionel Sambuc return 0;// expected-warning {{Potential leak of memory pointed to by}}
818f4a2713aSLionel Sambuc }
819f4a2713aSLionel Sambuc
820f4a2713aSLionel Sambuc extern void exit(int) __attribute__ ((__noreturn__));
mallocExit(int * g)821f4a2713aSLionel Sambuc void mallocExit(int *g) {
822f4a2713aSLionel Sambuc struct xx *p = malloc(12);
823f4a2713aSLionel Sambuc if (g != 0)
824f4a2713aSLionel Sambuc exit(1);
825f4a2713aSLionel Sambuc free(p);
826f4a2713aSLionel Sambuc return;
827f4a2713aSLionel Sambuc }
828f4a2713aSLionel Sambuc
829f4a2713aSLionel Sambuc extern void __assert_fail (__const char *__assertion, __const char *__file,
830f4a2713aSLionel Sambuc unsigned int __line, __const char *__function)
831f4a2713aSLionel Sambuc __attribute__ ((__noreturn__));
832f4a2713aSLionel Sambuc #define assert(expr) \
833f4a2713aSLionel Sambuc ((expr) ? (void)(0) : __assert_fail (#expr, __FILE__, __LINE__, __func__))
mallocAssert(int * g)834f4a2713aSLionel Sambuc void mallocAssert(int *g) {
835f4a2713aSLionel Sambuc struct xx *p = malloc(12);
836f4a2713aSLionel Sambuc
837f4a2713aSLionel Sambuc assert(g != 0);
838f4a2713aSLionel Sambuc free(p);
839f4a2713aSLionel Sambuc return;
840f4a2713aSLionel Sambuc }
841f4a2713aSLionel Sambuc
doNotInvalidateWhenPassedToSystemCalls(char * s)842f4a2713aSLionel Sambuc void doNotInvalidateWhenPassedToSystemCalls(char *s) {
843f4a2713aSLionel Sambuc char *p = malloc(12);
844f4a2713aSLionel Sambuc strlen(p);
845f4a2713aSLionel Sambuc strcpy(p, s);
846f4a2713aSLionel Sambuc strcpy(s, p);
847f4a2713aSLionel Sambuc strcpy(p, p);
848f4a2713aSLionel Sambuc memcpy(p, s, 1);
849f4a2713aSLionel Sambuc memcpy(s, p, 1);
850f4a2713aSLionel Sambuc memcpy(p, p, 1);
851f4a2713aSLionel Sambuc } // expected-warning {{leak}}
852f4a2713aSLionel Sambuc
853f4a2713aSLionel Sambuc // Treat source buffer contents as escaped.
escapeSourceContents(char * s)854f4a2713aSLionel Sambuc void escapeSourceContents(char *s) {
855f4a2713aSLionel Sambuc char *p = malloc(12);
856f4a2713aSLionel Sambuc memcpy(s, &p, 12); // no warning
857f4a2713aSLionel Sambuc
858f4a2713aSLionel Sambuc void *p1 = malloc(7);
859f4a2713aSLionel Sambuc char *a;
860f4a2713aSLionel Sambuc memcpy(&a, &p1, sizeof a);
861f4a2713aSLionel Sambuc // FIXME: No warning due to limitations imposed by current modelling of
862f4a2713aSLionel Sambuc // 'memcpy' (regions metadata is not copied).
863f4a2713aSLionel Sambuc
864f4a2713aSLionel Sambuc int *ptrs[2];
865f4a2713aSLionel Sambuc int *allocated = (int *)malloc(4);
866f4a2713aSLionel Sambuc memcpy(&ptrs[0], &allocated, sizeof(int *));
867f4a2713aSLionel Sambuc // FIXME: No warning due to limitations imposed by current modelling of
868f4a2713aSLionel Sambuc // 'memcpy' (regions metadata is not copied).
869f4a2713aSLionel Sambuc }
870f4a2713aSLionel Sambuc
invalidateDestinationContents()871f4a2713aSLionel Sambuc void invalidateDestinationContents() {
872f4a2713aSLionel Sambuc int *null = 0;
873f4a2713aSLionel Sambuc int *p = (int *)malloc(4);
874f4a2713aSLionel Sambuc memcpy(&p, &null, sizeof(int *));
875f4a2713aSLionel Sambuc
876f4a2713aSLionel Sambuc int *ptrs1[2]; // expected-warning {{Potential leak of memory pointed to by}}
877f4a2713aSLionel Sambuc ptrs1[0] = (int *)malloc(4);
878f4a2713aSLionel Sambuc memcpy(ptrs1, &null, sizeof(int *));
879f4a2713aSLionel Sambuc
880f4a2713aSLionel Sambuc int *ptrs2[2]; // expected-warning {{Potential memory leak}}
881f4a2713aSLionel Sambuc ptrs2[0] = (int *)malloc(4);
882f4a2713aSLionel Sambuc memcpy(&ptrs2[1], &null, sizeof(int *));
883f4a2713aSLionel Sambuc
884f4a2713aSLionel Sambuc int *ptrs3[2]; // expected-warning {{Potential memory leak}}
885f4a2713aSLionel Sambuc ptrs3[0] = (int *)malloc(4);
886f4a2713aSLionel Sambuc memcpy(&ptrs3[0], &null, sizeof(int *));
887f4a2713aSLionel Sambuc } // expected-warning {{Potential memory leak}}
888f4a2713aSLionel Sambuc
889f4a2713aSLionel Sambuc // Rely on the CString checker evaluation of the strcpy API to convey that the result of strcpy is equal to p.
symbolLostWithStrcpy(char * s)890f4a2713aSLionel Sambuc void symbolLostWithStrcpy(char *s) {
891f4a2713aSLionel Sambuc char *p = malloc(12);
892f4a2713aSLionel Sambuc p = strcpy(p, s);
893f4a2713aSLionel Sambuc free(p);
894f4a2713aSLionel Sambuc }
895f4a2713aSLionel Sambuc
896f4a2713aSLionel Sambuc
897f4a2713aSLionel Sambuc // The same test as the one above, but with what is actually generated on a mac.
898f4a2713aSLionel Sambuc static __inline char *
__inline_strcpy_chk(char * restrict __dest,const char * restrict __src)899f4a2713aSLionel Sambuc __inline_strcpy_chk (char *restrict __dest, const char *restrict __src)
900f4a2713aSLionel Sambuc {
901f4a2713aSLionel Sambuc return __builtin___strcpy_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1));
902f4a2713aSLionel Sambuc }
903f4a2713aSLionel Sambuc
symbolLostWithStrcpy_InlineStrcpyVersion(char * s)904f4a2713aSLionel Sambuc void symbolLostWithStrcpy_InlineStrcpyVersion(char *s) {
905f4a2713aSLionel Sambuc char *p = malloc(12);
906f4a2713aSLionel Sambuc 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));
907f4a2713aSLionel Sambuc free(p);
908f4a2713aSLionel Sambuc }
909f4a2713aSLionel Sambuc
910f4a2713aSLionel Sambuc // Here we are returning a pointer one past the allocated value. An idiom which
911f4a2713aSLionel Sambuc // can be used for implementing special malloc. The correct uses of this might
912f4a2713aSLionel Sambuc // be rare enough so that we could keep this as a warning.
specialMalloc(int n)913f4a2713aSLionel Sambuc static void *specialMalloc(int n){
914f4a2713aSLionel Sambuc int *p;
915f4a2713aSLionel Sambuc p = malloc( n+8 );
916f4a2713aSLionel Sambuc if( p ){
917f4a2713aSLionel Sambuc p[0] = n;
918f4a2713aSLionel Sambuc p++;
919f4a2713aSLionel Sambuc }
920f4a2713aSLionel Sambuc return p;
921f4a2713aSLionel Sambuc }
922f4a2713aSLionel Sambuc
923f4a2713aSLionel Sambuc // Potentially, the user could free the struct by performing pointer arithmetic on the return value.
924f4a2713aSLionel Sambuc // This is a variation of the specialMalloc issue, though probably would be more rare in correct code.
specialMallocWithStruct()925f4a2713aSLionel Sambuc int *specialMallocWithStruct() {
926f4a2713aSLionel Sambuc struct StructWithInt *px= malloc(sizeof(struct StructWithInt));
927f4a2713aSLionel Sambuc return &(px->g);
928f4a2713aSLionel Sambuc }
929f4a2713aSLionel Sambuc
930f4a2713aSLionel Sambuc // Test various allocation/deallocation functions.
testStrdup(const char * s,unsigned validIndex)931f4a2713aSLionel Sambuc void testStrdup(const char *s, unsigned validIndex) {
932f4a2713aSLionel Sambuc char *s2 = strdup(s);
933f4a2713aSLionel Sambuc s2[validIndex + 1] = 'b';
934f4a2713aSLionel Sambuc } // expected-warning {{Potential leak of memory pointed to by}}
935f4a2713aSLionel Sambuc
testStrndup(const char * s,unsigned validIndex,unsigned size)936f4a2713aSLionel Sambuc int testStrndup(const char *s, unsigned validIndex, unsigned size) {
937f4a2713aSLionel Sambuc char *s2 = strndup(s, size);
938f4a2713aSLionel Sambuc s2 [validIndex + 1] = 'b';
939f4a2713aSLionel Sambuc if (s2[validIndex] != 'a')
940f4a2713aSLionel Sambuc return 0;
941f4a2713aSLionel Sambuc else
942f4a2713aSLionel Sambuc return 1;// expected-warning {{Potential leak of memory pointed to by}}
943f4a2713aSLionel Sambuc }
944f4a2713aSLionel Sambuc
testStrdupContentIsDefined(const char * s,unsigned validIndex)945f4a2713aSLionel Sambuc void testStrdupContentIsDefined(const char *s, unsigned validIndex) {
946f4a2713aSLionel Sambuc char *s2 = strdup(s);
947f4a2713aSLionel Sambuc char result = s2[1];// no warning
948f4a2713aSLionel Sambuc free(s2);
949f4a2713aSLionel Sambuc }
950f4a2713aSLionel Sambuc
951f4a2713aSLionel Sambuc // ----------------------------------------------------------------------------
952f4a2713aSLionel Sambuc // Test the system library functions to which the pointer can escape.
953f4a2713aSLionel Sambuc // This tests false positive suppression.
954f4a2713aSLionel Sambuc
955f4a2713aSLionel Sambuc // For now, we assume memory passed to pthread_specific escapes.
956f4a2713aSLionel Sambuc // TODO: We could check that if a new pthread binding is set, the existing
957f4a2713aSLionel Sambuc // binding must be freed; otherwise, a memory leak can occur.
testPthereadSpecificEscape(pthread_key_t key)958f4a2713aSLionel Sambuc void testPthereadSpecificEscape(pthread_key_t key) {
959f4a2713aSLionel Sambuc void *buf = malloc(12);
960f4a2713aSLionel Sambuc pthread_setspecific(key, buf); // no warning
961f4a2713aSLionel Sambuc }
962f4a2713aSLionel Sambuc
963f4a2713aSLionel Sambuc // PR12101: Test funopen().
releasePtr(void * _ctx)964f4a2713aSLionel Sambuc static int releasePtr(void *_ctx) {
965f4a2713aSLionel Sambuc free(_ctx);
966f4a2713aSLionel Sambuc return 0;
967f4a2713aSLionel Sambuc }
useFunOpen()968f4a2713aSLionel Sambuc FILE *useFunOpen() {
969f4a2713aSLionel Sambuc void *ctx = malloc(sizeof(int));
970f4a2713aSLionel Sambuc FILE *f = funopen(ctx, 0, 0, 0, releasePtr); // no warning
971f4a2713aSLionel Sambuc if (f == 0) {
972f4a2713aSLionel Sambuc free(ctx);
973f4a2713aSLionel Sambuc }
974f4a2713aSLionel Sambuc return f;
975f4a2713aSLionel Sambuc }
useFunOpenNoReleaseFunction()976f4a2713aSLionel Sambuc FILE *useFunOpenNoReleaseFunction() {
977f4a2713aSLionel Sambuc void *ctx = malloc(sizeof(int));
978f4a2713aSLionel Sambuc FILE *f = funopen(ctx, 0, 0, 0, 0);
979f4a2713aSLionel Sambuc if (f == 0) {
980f4a2713aSLionel Sambuc free(ctx);
981f4a2713aSLionel Sambuc }
982f4a2713aSLionel Sambuc return f; // expected-warning{{leak}}
983f4a2713aSLionel Sambuc }
984f4a2713aSLionel Sambuc
readNothing(void * _ctx,char * buf,int size)985f4a2713aSLionel Sambuc static int readNothing(void *_ctx, char *buf, int size) {
986f4a2713aSLionel Sambuc return 0;
987f4a2713aSLionel Sambuc }
useFunOpenReadNoRelease()988f4a2713aSLionel Sambuc FILE *useFunOpenReadNoRelease() {
989f4a2713aSLionel Sambuc void *ctx = malloc(sizeof(int));
990f4a2713aSLionel Sambuc FILE *f = funopen(ctx, readNothing, 0, 0, 0);
991f4a2713aSLionel Sambuc if (f == 0) {
992f4a2713aSLionel Sambuc free(ctx);
993f4a2713aSLionel Sambuc }
994f4a2713aSLionel Sambuc return f; // expected-warning{{leak}}
995f4a2713aSLionel Sambuc }
996f4a2713aSLionel Sambuc
997f4a2713aSLionel Sambuc // Test setbuf, setvbuf.
my_main_no_warning()998f4a2713aSLionel Sambuc int my_main_no_warning() {
999f4a2713aSLionel Sambuc char *p = malloc(100);
1000f4a2713aSLionel Sambuc setvbuf(stdout, p, 0, 100);
1001f4a2713aSLionel Sambuc return 0;
1002f4a2713aSLionel Sambuc }
my_main_no_warning2()1003f4a2713aSLionel Sambuc int my_main_no_warning2() {
1004f4a2713aSLionel Sambuc char *p = malloc(100);
1005f4a2713aSLionel Sambuc setbuf(__stdoutp, p);
1006f4a2713aSLionel Sambuc return 0;
1007f4a2713aSLionel Sambuc }
my_main_warn(FILE * f)1008f4a2713aSLionel Sambuc int my_main_warn(FILE *f) {
1009f4a2713aSLionel Sambuc char *p = malloc(100);
1010f4a2713aSLionel Sambuc setvbuf(f, p, 0, 100);
1011f4a2713aSLionel Sambuc return 0;// expected-warning {{leak}}
1012f4a2713aSLionel Sambuc }
1013f4a2713aSLionel Sambuc
1014f4a2713aSLionel Sambuc // <rdar://problem/10978247>.
1015f4a2713aSLionel Sambuc // some people use stack allocated memory as an optimization to avoid
1016f4a2713aSLionel Sambuc // a heap allocation for small work sizes. This tests the analyzer's
1017f4a2713aSLionel Sambuc // understanding that the malloc'ed memory is not the same as stackBuffer.
radar10978247(int myValueSize)1018f4a2713aSLionel Sambuc void radar10978247(int myValueSize) {
1019f4a2713aSLionel Sambuc char stackBuffer[128];
1020f4a2713aSLionel Sambuc char *buffer;
1021f4a2713aSLionel Sambuc
1022f4a2713aSLionel Sambuc if (myValueSize <= sizeof(stackBuffer))
1023f4a2713aSLionel Sambuc buffer = stackBuffer;
1024f4a2713aSLionel Sambuc else
1025f4a2713aSLionel Sambuc buffer = malloc(myValueSize);
1026f4a2713aSLionel Sambuc
1027f4a2713aSLionel Sambuc // do stuff with the buffer
1028f4a2713aSLionel Sambuc if (buffer != stackBuffer)
1029f4a2713aSLionel Sambuc free(buffer);
1030f4a2713aSLionel Sambuc }
1031f4a2713aSLionel Sambuc
radar10978247_positive(int myValueSize)1032f4a2713aSLionel Sambuc void radar10978247_positive(int myValueSize) {
1033f4a2713aSLionel Sambuc char stackBuffer[128];
1034f4a2713aSLionel Sambuc char *buffer;
1035f4a2713aSLionel Sambuc
1036f4a2713aSLionel Sambuc if (myValueSize <= sizeof(stackBuffer))
1037f4a2713aSLionel Sambuc buffer = stackBuffer;
1038f4a2713aSLionel Sambuc else
1039f4a2713aSLionel Sambuc buffer = malloc(myValueSize);
1040f4a2713aSLionel Sambuc
1041f4a2713aSLionel Sambuc // do stuff with the buffer
1042f4a2713aSLionel Sambuc if (buffer == stackBuffer)
1043f4a2713aSLionel Sambuc return;
1044f4a2713aSLionel Sambuc else
1045f4a2713aSLionel Sambuc return; // expected-warning {{leak}}
1046f4a2713aSLionel Sambuc }
1047f4a2713aSLionel Sambuc // <rdar://problem/11269741> Previously this triggered a false positive
1048f4a2713aSLionel Sambuc // because malloc() is known to return uninitialized memory and the binding
1049f4a2713aSLionel Sambuc // of 'o' to 'p->n' was not getting propertly handled. Now we report a leak.
1050f4a2713aSLionel Sambuc struct rdar11269741_a_t {
1051f4a2713aSLionel Sambuc struct rdar11269741_b_t {
1052f4a2713aSLionel Sambuc int m;
1053f4a2713aSLionel Sambuc } n;
1054f4a2713aSLionel Sambuc };
1055f4a2713aSLionel Sambuc
rdar11269741(struct rdar11269741_b_t o)1056f4a2713aSLionel Sambuc int rdar11269741(struct rdar11269741_b_t o)
1057f4a2713aSLionel Sambuc {
1058f4a2713aSLionel Sambuc struct rdar11269741_a_t *p = (struct rdar11269741_a_t *) malloc(sizeof(*p));
1059f4a2713aSLionel Sambuc p->n = o;
1060f4a2713aSLionel Sambuc return p->n.m; // expected-warning {{leak}}
1061f4a2713aSLionel Sambuc }
1062f4a2713aSLionel Sambuc
1063f4a2713aSLionel Sambuc // Pointer arithmetic, returning an ElementRegion.
radar11329382(unsigned bl)1064f4a2713aSLionel Sambuc void *radar11329382(unsigned bl) {
1065f4a2713aSLionel Sambuc void *ptr = malloc (16);
1066f4a2713aSLionel Sambuc ptr = ptr + (2 - bl);
1067f4a2713aSLionel Sambuc return ptr; // no warning
1068f4a2713aSLionel Sambuc }
1069f4a2713aSLionel Sambuc
1070f4a2713aSLionel Sambuc void __assert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__));
1071f4a2713aSLionel Sambuc int strcmp(const char *, const char *);
1072f4a2713aSLionel Sambuc char *a (void);
radar11270219(void)1073f4a2713aSLionel Sambuc void radar11270219(void) {
1074f4a2713aSLionel Sambuc char *x = a(), *y = a();
1075f4a2713aSLionel Sambuc (__builtin_expect(!(x && y), 0) ? __assert_rtn(__func__, "/Users/zaks/tmp/ex.c", 24, "x && y") : (void)0);
1076f4a2713aSLionel Sambuc strcmp(x, y); // no warning
1077f4a2713aSLionel Sambuc }
1078f4a2713aSLionel Sambuc
radar_11358224_test_double_assign_ints_positive_2()1079f4a2713aSLionel Sambuc void radar_11358224_test_double_assign_ints_positive_2()
1080f4a2713aSLionel Sambuc {
1081f4a2713aSLionel Sambuc void *ptr = malloc(16);
1082f4a2713aSLionel Sambuc ptr = ptr;
1083f4a2713aSLionel Sambuc } // expected-warning {{leak}}
1084f4a2713aSLionel Sambuc
1085f4a2713aSLionel Sambuc // Assume that functions which take a function pointer can free memory even if
1086f4a2713aSLionel Sambuc // they are defined in system headers and take the const pointer to the
1087f4a2713aSLionel Sambuc // allocated memory. (radar://11160612)
1088f4a2713aSLionel Sambuc int const_ptr_and_callback(int, const char*, int n, void(*)(void*));
r11160612_1()1089f4a2713aSLionel Sambuc void r11160612_1() {
1090f4a2713aSLionel Sambuc char *x = malloc(12);
1091f4a2713aSLionel Sambuc const_ptr_and_callback(0, x, 12, free); // no - warning
1092f4a2713aSLionel Sambuc }
1093f4a2713aSLionel Sambuc
1094f4a2713aSLionel Sambuc // Null is passed as callback.
r11160612_2()1095f4a2713aSLionel Sambuc void r11160612_2() {
1096f4a2713aSLionel Sambuc char *x = malloc(12);
1097f4a2713aSLionel Sambuc const_ptr_and_callback(0, x, 12, 0);
1098f4a2713aSLionel Sambuc } // expected-warning {{leak}}
1099f4a2713aSLionel Sambuc
1100f4a2713aSLionel Sambuc // Callback is passed to a function defined in a system header.
r11160612_4()1101f4a2713aSLionel Sambuc void r11160612_4() {
1102f4a2713aSLionel Sambuc char *x = malloc(12);
1103f4a2713aSLionel Sambuc sqlite3_bind_text_my(0, x, 12, free); // no - warning
1104f4a2713aSLionel Sambuc }
1105f4a2713aSLionel Sambuc
1106f4a2713aSLionel Sambuc // Passing callbacks in a struct.
r11160612_5(StWithCallback St)1107f4a2713aSLionel Sambuc void r11160612_5(StWithCallback St) {
1108f4a2713aSLionel Sambuc void *x = malloc(12);
1109f4a2713aSLionel Sambuc dealocateMemWhenDoneByVal(x, St);
1110f4a2713aSLionel Sambuc }
r11160612_6(StWithCallback St)1111f4a2713aSLionel Sambuc void r11160612_6(StWithCallback St) {
1112f4a2713aSLionel Sambuc void *x = malloc(12);
1113f4a2713aSLionel Sambuc dealocateMemWhenDoneByRef(&St, x);
1114f4a2713aSLionel Sambuc }
1115f4a2713aSLionel Sambuc
1116f4a2713aSLionel Sambuc int mySub(int, int);
1117f4a2713aSLionel Sambuc int myAdd(int, int);
fPtr(unsigned cond,int x)1118f4a2713aSLionel Sambuc int fPtr(unsigned cond, int x) {
1119f4a2713aSLionel Sambuc return (cond ? mySub : myAdd)(x, x);
1120f4a2713aSLionel Sambuc }
1121f4a2713aSLionel Sambuc
1122f4a2713aSLionel Sambuc // Test anti-aliasing.
1123f4a2713aSLionel Sambuc
dependsOnValueOfPtr(int * g,unsigned f)1124f4a2713aSLionel Sambuc void dependsOnValueOfPtr(int *g, unsigned f) {
1125f4a2713aSLionel Sambuc int *p;
1126f4a2713aSLionel Sambuc
1127f4a2713aSLionel Sambuc if (f) {
1128f4a2713aSLionel Sambuc p = g;
1129f4a2713aSLionel Sambuc } else {
1130f4a2713aSLionel Sambuc p = malloc(12);
1131f4a2713aSLionel Sambuc }
1132f4a2713aSLionel Sambuc
1133f4a2713aSLionel Sambuc if (p != g)
1134f4a2713aSLionel Sambuc free(p);
1135f4a2713aSLionel Sambuc else
1136f4a2713aSLionel Sambuc return; // no warning
1137f4a2713aSLionel Sambuc return;
1138f4a2713aSLionel Sambuc }
1139f4a2713aSLionel Sambuc
CMPRegionHeapToStack()1140f4a2713aSLionel Sambuc int CMPRegionHeapToStack() {
1141f4a2713aSLionel Sambuc int x = 0;
1142f4a2713aSLionel Sambuc int *x1 = malloc(8);
1143f4a2713aSLionel Sambuc int *x2 = &x;
1144f4a2713aSLionel Sambuc clang_analyzer_eval(x1 == x2); // expected-warning{{FALSE}}
1145f4a2713aSLionel Sambuc free(x1);
1146f4a2713aSLionel Sambuc return x;
1147f4a2713aSLionel Sambuc }
1148f4a2713aSLionel Sambuc
CMPRegionHeapToHeap2()1149f4a2713aSLionel Sambuc int CMPRegionHeapToHeap2() {
1150f4a2713aSLionel Sambuc int x = 0;
1151f4a2713aSLionel Sambuc int *x1 = malloc(8);
1152f4a2713aSLionel Sambuc int *x2 = malloc(8);
1153f4a2713aSLionel Sambuc int *x4 = x1;
1154f4a2713aSLionel Sambuc int *x5 = x2;
1155f4a2713aSLionel Sambuc clang_analyzer_eval(x4 == x5); // expected-warning{{FALSE}}
1156f4a2713aSLionel Sambuc free(x1);
1157f4a2713aSLionel Sambuc free(x2);
1158f4a2713aSLionel Sambuc return x;
1159f4a2713aSLionel Sambuc }
1160f4a2713aSLionel Sambuc
CMPRegionHeapToHeap()1161f4a2713aSLionel Sambuc int CMPRegionHeapToHeap() {
1162f4a2713aSLionel Sambuc int x = 0;
1163f4a2713aSLionel Sambuc int *x1 = malloc(8);
1164f4a2713aSLionel Sambuc int *x4 = x1;
1165f4a2713aSLionel Sambuc if (x1 == x4) {
1166f4a2713aSLionel Sambuc free(x1);
1167f4a2713aSLionel Sambuc return 5/x; // expected-warning{{Division by zero}}
1168f4a2713aSLionel Sambuc }
1169f4a2713aSLionel Sambuc return x;// expected-warning{{This statement is never executed}}
1170f4a2713aSLionel Sambuc }
1171f4a2713aSLionel Sambuc
HeapAssignment()1172f4a2713aSLionel Sambuc int HeapAssignment() {
1173f4a2713aSLionel Sambuc int m = 0;
1174f4a2713aSLionel Sambuc int *x = malloc(4);
1175f4a2713aSLionel Sambuc int *y = x;
1176f4a2713aSLionel Sambuc *x = 5;
1177f4a2713aSLionel Sambuc clang_analyzer_eval(*x != *y); // expected-warning{{FALSE}}
1178f4a2713aSLionel Sambuc free(x);
1179f4a2713aSLionel Sambuc return 0;
1180f4a2713aSLionel Sambuc }
1181f4a2713aSLionel Sambuc
1182f4a2713aSLionel Sambuc int *retPtr();
1183f4a2713aSLionel Sambuc int *retPtrMightAlias(int *x);
cmpHeapAllocationToUnknown()1184f4a2713aSLionel Sambuc int cmpHeapAllocationToUnknown() {
1185f4a2713aSLionel Sambuc int zero = 0;
1186f4a2713aSLionel Sambuc int *yBefore = retPtr();
1187f4a2713aSLionel Sambuc int *m = malloc(8);
1188f4a2713aSLionel Sambuc int *yAfter = retPtrMightAlias(m);
1189f4a2713aSLionel Sambuc clang_analyzer_eval(yBefore == m); // expected-warning{{FALSE}}
1190f4a2713aSLionel Sambuc clang_analyzer_eval(yAfter == m); // expected-warning{{FALSE}}
1191f4a2713aSLionel Sambuc free(m);
1192f4a2713aSLionel Sambuc return 0;
1193f4a2713aSLionel Sambuc }
1194f4a2713aSLionel Sambuc
localArrayTest()1195f4a2713aSLionel Sambuc void localArrayTest() {
1196f4a2713aSLionel Sambuc char *p = (char*)malloc(12);
1197f4a2713aSLionel Sambuc char *ArrayL[12];
1198f4a2713aSLionel Sambuc ArrayL[0] = p;
1199f4a2713aSLionel Sambuc } // expected-warning {{leak}}
1200f4a2713aSLionel Sambuc
localStructTest()1201f4a2713aSLionel Sambuc void localStructTest() {
1202f4a2713aSLionel Sambuc StructWithPtr St;
1203f4a2713aSLionel Sambuc StructWithPtr *pSt = &St;
1204f4a2713aSLionel Sambuc pSt->memP = malloc(12);
1205f4a2713aSLionel Sambuc } // expected-warning{{Potential leak of memory pointed to by}}
1206f4a2713aSLionel Sambuc
1207f4a2713aSLionel Sambuc #ifdef __INTPTR_TYPE__
1208f4a2713aSLionel Sambuc // Test double assignment through integers.
1209f4a2713aSLionel Sambuc typedef __INTPTR_TYPE__ intptr_t;
1210f4a2713aSLionel Sambuc typedef unsigned __INTPTR_TYPE__ uintptr_t;
1211f4a2713aSLionel Sambuc
1212f4a2713aSLionel Sambuc static intptr_t glob;
test_double_assign_ints()1213f4a2713aSLionel Sambuc void test_double_assign_ints()
1214f4a2713aSLionel Sambuc {
1215f4a2713aSLionel Sambuc void *ptr = malloc (16); // no-warning
1216f4a2713aSLionel Sambuc glob = (intptr_t)(uintptr_t)ptr;
1217f4a2713aSLionel Sambuc }
1218f4a2713aSLionel Sambuc
test_double_assign_ints_positive()1219f4a2713aSLionel Sambuc void test_double_assign_ints_positive()
1220f4a2713aSLionel Sambuc {
1221f4a2713aSLionel Sambuc void *ptr = malloc(16);
1222f4a2713aSLionel Sambuc (void*)(intptr_t)(uintptr_t)ptr; // expected-warning {{unused}}
1223f4a2713aSLionel Sambuc } // expected-warning {{leak}}
1224f4a2713aSLionel Sambuc #endif
1225f4a2713aSLionel Sambuc
testCGContextNoLeak()1226f4a2713aSLionel Sambuc void testCGContextNoLeak()
1227f4a2713aSLionel Sambuc {
1228f4a2713aSLionel Sambuc void *ptr = malloc(16);
1229f4a2713aSLionel Sambuc CGContextRef context = CGBitmapContextCreate(ptr);
1230f4a2713aSLionel Sambuc
1231f4a2713aSLionel Sambuc // Because you can get the data back out like this, even much later,
1232f4a2713aSLionel Sambuc // CGBitmapContextCreate is one of our "stop-tracking" exceptions.
1233f4a2713aSLionel Sambuc free(CGBitmapContextGetData(context));
1234f4a2713aSLionel Sambuc }
1235f4a2713aSLionel Sambuc
testCGContextLeak()1236f4a2713aSLionel Sambuc void testCGContextLeak()
1237f4a2713aSLionel Sambuc {
1238f4a2713aSLionel Sambuc void *ptr = malloc(16);
1239f4a2713aSLionel Sambuc CGContextRef context = CGBitmapContextCreate(ptr);
1240f4a2713aSLionel Sambuc // However, this time we're just leaking the data, because the context
1241f4a2713aSLionel Sambuc // object doesn't escape and it hasn't been freed in this function.
1242f4a2713aSLionel Sambuc }
1243f4a2713aSLionel Sambuc
1244f4a2713aSLionel Sambuc // Allow xpc context to escape. radar://11635258
1245f4a2713aSLionel Sambuc // TODO: Would be great if we checked that the finalize_connection_context actually releases it.
finalize_connection_context(void * ctx)1246f4a2713aSLionel Sambuc static void finalize_connection_context(void *ctx) {
1247f4a2713aSLionel Sambuc int *context = ctx;
1248f4a2713aSLionel Sambuc free(context);
1249f4a2713aSLionel Sambuc }
foo(xpc_connection_t peer)1250f4a2713aSLionel Sambuc void foo (xpc_connection_t peer) {
1251f4a2713aSLionel Sambuc int *ctx = calloc(1, sizeof(int));
1252f4a2713aSLionel Sambuc xpc_connection_set_context(peer, ctx);
1253f4a2713aSLionel Sambuc xpc_connection_set_finalizer_f(peer, finalize_connection_context);
1254f4a2713aSLionel Sambuc xpc_connection_resume(peer);
1255f4a2713aSLionel Sambuc }
1256f4a2713aSLionel Sambuc
1257f4a2713aSLionel Sambuc // Make sure we catch errors when we free in a function which does not allocate memory.
freeButNoMalloc(int * p,int x)1258f4a2713aSLionel Sambuc void freeButNoMalloc(int *p, int x){
1259f4a2713aSLionel Sambuc if (x) {
1260f4a2713aSLionel Sambuc free(p);
1261f4a2713aSLionel Sambuc //user forgot a return here.
1262f4a2713aSLionel Sambuc }
1263f4a2713aSLionel Sambuc free(p); // expected-warning {{Attempt to free released memory}}
1264f4a2713aSLionel Sambuc }
1265f4a2713aSLionel Sambuc
1266f4a2713aSLionel Sambuc struct HasPtr {
1267f4a2713aSLionel Sambuc char *p;
1268f4a2713aSLionel Sambuc };
1269f4a2713aSLionel Sambuc
reallocButNoMalloc(struct HasPtr * a,int c,int size)1270f4a2713aSLionel Sambuc char* reallocButNoMalloc(struct HasPtr *a, int c, int size) {
1271f4a2713aSLionel Sambuc int *s;
1272f4a2713aSLionel Sambuc char *b = realloc(a->p, size);
1273f4a2713aSLionel Sambuc char *m = realloc(a->p, size); // expected-warning {{Attempt to free released memory}}
1274f4a2713aSLionel Sambuc return a->p;
1275f4a2713aSLionel Sambuc }
1276f4a2713aSLionel Sambuc
1277f4a2713aSLionel Sambuc // We should not warn in this case since the caller will presumably free a->p in all cases.
reallocButNoMallocPR13674(struct HasPtr * a,int c,int size)1278f4a2713aSLionel Sambuc int reallocButNoMallocPR13674(struct HasPtr *a, int c, int size) {
1279f4a2713aSLionel Sambuc int *s;
1280f4a2713aSLionel Sambuc char *b = realloc(a->p, size);
1281f4a2713aSLionel Sambuc if (b == 0)
1282f4a2713aSLionel Sambuc return -1;
1283f4a2713aSLionel Sambuc a->p = b;
1284f4a2713aSLionel Sambuc return 0;
1285f4a2713aSLionel Sambuc }
1286f4a2713aSLionel Sambuc
1287f4a2713aSLionel Sambuc // Test realloc with no visible malloc.
test(void * ptr)1288f4a2713aSLionel Sambuc void *test(void *ptr) {
1289f4a2713aSLionel Sambuc void *newPtr = realloc(ptr, 4);
1290f4a2713aSLionel Sambuc if (newPtr == 0) {
1291f4a2713aSLionel Sambuc if (ptr)
1292f4a2713aSLionel Sambuc free(ptr); // no-warning
1293f4a2713aSLionel Sambuc }
1294f4a2713aSLionel Sambuc return newPtr;
1295f4a2713aSLionel Sambuc }
1296f4a2713aSLionel Sambuc
1297f4a2713aSLionel Sambuc
testLeakWithinReturn(char * str)1298f4a2713aSLionel Sambuc char *testLeakWithinReturn(char *str) {
1299f4a2713aSLionel Sambuc return strdup(strdup(str)); // expected-warning{{leak}}
1300f4a2713aSLionel Sambuc }
1301f4a2713aSLionel Sambuc
1302f4a2713aSLionel Sambuc void passConstPtr(const char * ptr);
1303f4a2713aSLionel Sambuc
testPassConstPointer()1304f4a2713aSLionel Sambuc void testPassConstPointer() {
1305f4a2713aSLionel Sambuc char * string = malloc(sizeof(char)*10);
1306f4a2713aSLionel Sambuc passConstPtr(string);
1307f4a2713aSLionel Sambuc return; // expected-warning {{leak}}
1308f4a2713aSLionel Sambuc }
1309f4a2713aSLionel Sambuc
testPassConstPointerIndirectly()1310f4a2713aSLionel Sambuc void testPassConstPointerIndirectly() {
1311f4a2713aSLionel Sambuc char *p = malloc(1);
1312f4a2713aSLionel Sambuc p++;
1313f4a2713aSLionel Sambuc memcmp(p, p, sizeof(&p));
1314f4a2713aSLionel Sambuc return; // expected-warning {{leak}}
1315f4a2713aSLionel Sambuc }
1316f4a2713aSLionel Sambuc
testPassConstPointerIndirectlyStruct()1317f4a2713aSLionel Sambuc void testPassConstPointerIndirectlyStruct() {
1318f4a2713aSLionel Sambuc struct HasPtr hp;
1319f4a2713aSLionel Sambuc hp.p = malloc(10);
1320f4a2713aSLionel Sambuc memcmp(&hp, &hp, sizeof(hp));
1321f4a2713aSLionel Sambuc return; // expected-warning {{Potential leak of memory pointed to by 'hp.p'}}
1322f4a2713aSLionel Sambuc }
1323f4a2713aSLionel Sambuc
testPassToSystemHeaderFunctionIndirectlyStruct()1324f4a2713aSLionel Sambuc void testPassToSystemHeaderFunctionIndirectlyStruct() {
1325f4a2713aSLionel Sambuc SomeStruct ss;
1326f4a2713aSLionel Sambuc ss.p = malloc(1);
1327f4a2713aSLionel Sambuc fakeSystemHeaderCall(&ss); // invalidates ss, making ss.p unreachable
1328f4a2713aSLionel Sambuc // Technically a false negative here -- we know the system function won't free
1329f4a2713aSLionel Sambuc // ss.p, but nothing else will either!
1330f4a2713aSLionel Sambuc } // no-warning
1331f4a2713aSLionel Sambuc
testPassToSystemHeaderFunctionIndirectlyStructFree()1332f4a2713aSLionel Sambuc void testPassToSystemHeaderFunctionIndirectlyStructFree() {
1333f4a2713aSLionel Sambuc SomeStruct ss;
1334f4a2713aSLionel Sambuc ss.p = malloc(1);
1335f4a2713aSLionel Sambuc fakeSystemHeaderCall(&ss); // invalidates ss, making ss.p unreachable
1336f4a2713aSLionel Sambuc free(ss.p);
1337f4a2713aSLionel Sambuc } // no-warning
1338f4a2713aSLionel Sambuc
testPassToSystemHeaderFunctionIndirectlyArray()1339f4a2713aSLionel Sambuc void testPassToSystemHeaderFunctionIndirectlyArray() {
1340f4a2713aSLionel Sambuc int *p[1];
1341f4a2713aSLionel Sambuc p[0] = malloc(sizeof(int));
1342f4a2713aSLionel Sambuc fakeSystemHeaderCallIntPtr(p); // invalidates p, making p[0] unreachable
1343f4a2713aSLionel Sambuc // Technically a false negative here -- we know the system function won't free
1344f4a2713aSLionel Sambuc // p[0], but nothing else will either!
1345f4a2713aSLionel Sambuc } // no-warning
1346f4a2713aSLionel Sambuc
testPassToSystemHeaderFunctionIndirectlyArrayFree()1347f4a2713aSLionel Sambuc void testPassToSystemHeaderFunctionIndirectlyArrayFree() {
1348f4a2713aSLionel Sambuc int *p[1];
1349f4a2713aSLionel Sambuc p[0] = malloc(sizeof(int));
1350f4a2713aSLionel Sambuc fakeSystemHeaderCallIntPtr(p); // invalidates p, making p[0] unreachable
1351f4a2713aSLionel Sambuc free(p[0]);
1352f4a2713aSLionel Sambuc } // no-warning
1353f4a2713aSLionel Sambuc
testOffsetAllocate(size_t size)1354f4a2713aSLionel Sambuc int *testOffsetAllocate(size_t size) {
1355f4a2713aSLionel Sambuc int *memoryBlock = (int *)malloc(size + sizeof(int));
1356f4a2713aSLionel Sambuc return &memoryBlock[1]; // no-warning
1357f4a2713aSLionel Sambuc }
1358f4a2713aSLionel Sambuc
testOffsetDeallocate(int * memoryBlock)1359f4a2713aSLionel Sambuc void testOffsetDeallocate(int *memoryBlock) {
1360f4a2713aSLionel Sambuc free(&memoryBlock[-1]); // no-warning
1361f4a2713aSLionel Sambuc }
1362f4a2713aSLionel Sambuc
testOffsetOfRegionFreed()1363f4a2713aSLionel Sambuc void testOffsetOfRegionFreed() {
1364f4a2713aSLionel Sambuc __int64_t * array = malloc(sizeof(__int64_t)*2);
1365f4a2713aSLionel Sambuc array += 1;
1366f4a2713aSLionel Sambuc free(&array[0]); // expected-warning{{Argument to free() is offset by 8 bytes from the start of memory allocated by malloc()}}
1367f4a2713aSLionel Sambuc }
1368f4a2713aSLionel Sambuc
testOffsetOfRegionFreed2()1369f4a2713aSLionel Sambuc void testOffsetOfRegionFreed2() {
1370f4a2713aSLionel Sambuc __int64_t *p = malloc(sizeof(__int64_t)*2);
1371f4a2713aSLionel Sambuc p += 1;
1372f4a2713aSLionel Sambuc free(p); // expected-warning{{Argument to free() is offset by 8 bytes from the start of memory allocated by malloc()}}
1373f4a2713aSLionel Sambuc }
1374f4a2713aSLionel Sambuc
testOffsetOfRegionFreed3()1375f4a2713aSLionel Sambuc void testOffsetOfRegionFreed3() {
1376f4a2713aSLionel Sambuc char *r = malloc(sizeof(char));
1377f4a2713aSLionel Sambuc r = r - 10;
1378f4a2713aSLionel Sambuc free(r); // expected-warning {{Argument to free() is offset by -10 bytes from the start of memory allocated by malloc()}}
1379f4a2713aSLionel Sambuc }
1380f4a2713aSLionel Sambuc
testOffsetOfRegionFreedAfterFunctionCall()1381f4a2713aSLionel Sambuc void testOffsetOfRegionFreedAfterFunctionCall() {
1382f4a2713aSLionel Sambuc int *p = malloc(sizeof(int)*2);
1383f4a2713aSLionel Sambuc p += 1;
1384f4a2713aSLionel Sambuc myfoo(p);
1385f4a2713aSLionel Sambuc free(p); // expected-warning{{Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()}}
1386f4a2713aSLionel Sambuc }
1387f4a2713aSLionel Sambuc
testFixManipulatedPointerBeforeFree()1388f4a2713aSLionel Sambuc void testFixManipulatedPointerBeforeFree() {
1389f4a2713aSLionel Sambuc int * array = malloc(sizeof(int)*2);
1390f4a2713aSLionel Sambuc array += 1;
1391f4a2713aSLionel Sambuc free(&array[-1]); // no-warning
1392f4a2713aSLionel Sambuc }
1393f4a2713aSLionel Sambuc
testFixManipulatedPointerBeforeFree2()1394f4a2713aSLionel Sambuc void testFixManipulatedPointerBeforeFree2() {
1395f4a2713aSLionel Sambuc char *r = malloc(sizeof(char));
1396f4a2713aSLionel Sambuc r = r + 10;
1397f4a2713aSLionel Sambuc free(r-10); // no-warning
1398f4a2713aSLionel Sambuc }
1399f4a2713aSLionel Sambuc
freeOffsetPointerPassedToFunction()1400f4a2713aSLionel Sambuc void freeOffsetPointerPassedToFunction() {
1401f4a2713aSLionel Sambuc __int64_t *p = malloc(sizeof(__int64_t)*2);
1402f4a2713aSLionel Sambuc p[1] = 0;
1403f4a2713aSLionel Sambuc p += 1;
1404f4a2713aSLionel Sambuc myfooint(*p); // not passing the pointer, only a value pointed by pointer
1405f4a2713aSLionel Sambuc free(p); // expected-warning {{Argument to free() is offset by 8 bytes from the start of memory allocated by malloc()}}
1406f4a2713aSLionel Sambuc }
1407f4a2713aSLionel Sambuc
1408f4a2713aSLionel Sambuc int arbitraryInt();
freeUnknownOffsetPointer()1409f4a2713aSLionel Sambuc void freeUnknownOffsetPointer() {
1410f4a2713aSLionel Sambuc char *r = malloc(sizeof(char));
1411f4a2713aSLionel Sambuc r = r + arbitraryInt(); // unable to reason about what the offset might be
1412f4a2713aSLionel Sambuc free(r); // no-warning
1413f4a2713aSLionel Sambuc }
1414f4a2713aSLionel Sambuc
testFreeNonMallocPointerWithNoOffset()1415f4a2713aSLionel Sambuc void testFreeNonMallocPointerWithNoOffset() {
1416f4a2713aSLionel Sambuc char c;
1417f4a2713aSLionel Sambuc char *r = &c;
1418f4a2713aSLionel Sambuc r = r + 10;
1419f4a2713aSLionel Sambuc free(r-10); // expected-warning {{Argument to free() is the address of the local variable 'c', which is not memory allocated by malloc()}}
1420f4a2713aSLionel Sambuc }
1421f4a2713aSLionel Sambuc
testFreeNonMallocPointerWithOffset()1422f4a2713aSLionel Sambuc void testFreeNonMallocPointerWithOffset() {
1423f4a2713aSLionel Sambuc char c;
1424f4a2713aSLionel Sambuc char *r = &c;
1425f4a2713aSLionel Sambuc free(r+1); // expected-warning {{Argument to free() is the address of the local variable 'c', which is not memory allocated by malloc()}}
1426f4a2713aSLionel Sambuc }
1427f4a2713aSLionel Sambuc
testOffsetZeroDoubleFree()1428f4a2713aSLionel Sambuc void testOffsetZeroDoubleFree() {
1429f4a2713aSLionel Sambuc int *array = malloc(sizeof(int)*2);
1430f4a2713aSLionel Sambuc int *p = &array[0];
1431f4a2713aSLionel Sambuc free(p);
1432f4a2713aSLionel Sambuc free(&array[0]); // expected-warning{{Attempt to free released memory}}
1433f4a2713aSLionel Sambuc }
1434f4a2713aSLionel Sambuc
testOffsetPassedToStrlen()1435f4a2713aSLionel Sambuc void testOffsetPassedToStrlen() {
1436f4a2713aSLionel Sambuc char * string = malloc(sizeof(char)*10);
1437f4a2713aSLionel Sambuc string += 1;
1438f4a2713aSLionel Sambuc int length = strlen(string); // expected-warning {{Potential leak of memory pointed to by 'string'}}
1439f4a2713aSLionel Sambuc }
1440f4a2713aSLionel Sambuc
testOffsetPassedToStrlenThenFree()1441f4a2713aSLionel Sambuc void testOffsetPassedToStrlenThenFree() {
1442f4a2713aSLionel Sambuc char * string = malloc(sizeof(char)*10);
1443f4a2713aSLionel Sambuc string += 1;
1444f4a2713aSLionel Sambuc int length = strlen(string);
1445f4a2713aSLionel Sambuc free(string); // expected-warning {{Argument to free() is offset by 1 byte from the start of memory allocated by malloc()}}
1446f4a2713aSLionel Sambuc }
1447f4a2713aSLionel Sambuc
testOffsetPassedAsConst()1448f4a2713aSLionel Sambuc void testOffsetPassedAsConst() {
1449f4a2713aSLionel Sambuc char * string = malloc(sizeof(char)*10);
1450f4a2713aSLionel Sambuc string += 1;
1451f4a2713aSLionel Sambuc passConstPtr(string);
1452f4a2713aSLionel Sambuc free(string); // expected-warning {{Argument to free() is offset by 1 byte from the start of memory allocated by malloc()}}
1453f4a2713aSLionel Sambuc }
1454f4a2713aSLionel Sambuc
1455f4a2713aSLionel Sambuc char **_vectorSegments;
1456f4a2713aSLionel Sambuc int _nVectorSegments;
1457f4a2713aSLionel Sambuc
poolFreeC(void * s)1458f4a2713aSLionel Sambuc void poolFreeC(void* s) {
1459f4a2713aSLionel Sambuc free(s); // no-warning
1460f4a2713aSLionel Sambuc }
freeMemory()1461f4a2713aSLionel Sambuc void freeMemory() {
1462f4a2713aSLionel Sambuc while (_nVectorSegments) {
1463f4a2713aSLionel Sambuc poolFreeC(_vectorSegments[_nVectorSegments++]);
1464f4a2713aSLionel Sambuc }
1465f4a2713aSLionel Sambuc }
1466f4a2713aSLionel Sambuc
1467f4a2713aSLionel Sambuc // PR16730
testReallocEscaped(void ** memory)1468f4a2713aSLionel Sambuc void testReallocEscaped(void **memory) {
1469f4a2713aSLionel Sambuc *memory = malloc(47);
1470f4a2713aSLionel Sambuc char *new_memory = realloc(*memory, 47);
1471f4a2713aSLionel Sambuc if (new_memory != 0) {
1472f4a2713aSLionel Sambuc *memory = new_memory;
1473f4a2713aSLionel Sambuc }
1474f4a2713aSLionel Sambuc }
1475f4a2713aSLionel Sambuc
1476f4a2713aSLionel Sambuc // PR16558
smallocNoWarn(size_t size)1477f4a2713aSLionel Sambuc void *smallocNoWarn(size_t size) {
1478f4a2713aSLionel Sambuc if (size == 0) {
1479f4a2713aSLionel Sambuc return malloc(1); // this branch is never called
1480f4a2713aSLionel Sambuc }
1481f4a2713aSLionel Sambuc else {
1482f4a2713aSLionel Sambuc return malloc(size);
1483f4a2713aSLionel Sambuc }
1484f4a2713aSLionel Sambuc }
1485f4a2713aSLionel Sambuc
dupstrNoWarn(const char * s)1486f4a2713aSLionel Sambuc char *dupstrNoWarn(const char *s) {
1487f4a2713aSLionel Sambuc const int len = strlen(s);
1488f4a2713aSLionel Sambuc char *p = (char*) smallocNoWarn(len + 1);
1489f4a2713aSLionel Sambuc strcpy(p, s); // no-warning
1490f4a2713aSLionel Sambuc return p;
1491f4a2713aSLionel Sambuc }
1492f4a2713aSLionel Sambuc
smallocWarn(size_t size)1493f4a2713aSLionel Sambuc void *smallocWarn(size_t size) {
1494f4a2713aSLionel Sambuc if (size == 2) {
1495f4a2713aSLionel Sambuc return malloc(1);
1496f4a2713aSLionel Sambuc }
1497f4a2713aSLionel Sambuc else {
1498f4a2713aSLionel Sambuc return malloc(size);
1499f4a2713aSLionel Sambuc }
1500f4a2713aSLionel Sambuc }
1501f4a2713aSLionel Sambuc
dupstrWarn(const char * s)1502f4a2713aSLionel Sambuc char *dupstrWarn(const char *s) {
1503f4a2713aSLionel Sambuc const int len = strlen(s);
1504f4a2713aSLionel Sambuc char *p = (char*) smallocWarn(len + 1);
1505f4a2713aSLionel Sambuc strcpy(p, s); // expected-warning{{String copy function overflows destination buffer}}
1506f4a2713aSLionel Sambuc return p;
1507f4a2713aSLionel Sambuc }
1508f4a2713aSLionel Sambuc
radar15580979()1509*0a6a1f1dSLionel Sambuc int *radar15580979() {
1510*0a6a1f1dSLionel Sambuc int *data = (int *)malloc(32);
1511*0a6a1f1dSLionel Sambuc int *p = data ?: (int*)malloc(32); // no warning
1512*0a6a1f1dSLionel Sambuc return p;
1513*0a6a1f1dSLionel Sambuc }
1514*0a6a1f1dSLionel Sambuc
1515f4a2713aSLionel Sambuc // ----------------------------------------------------------------------------
1516f4a2713aSLionel Sambuc // False negatives.
1517f4a2713aSLionel Sambuc
testMallocWithParam(int ** p)1518f4a2713aSLionel Sambuc void testMallocWithParam(int **p) {
1519f4a2713aSLionel Sambuc *p = (int*) malloc(sizeof(int));
1520f4a2713aSLionel Sambuc *p = 0; // FIXME: should warn here
1521f4a2713aSLionel Sambuc }
1522f4a2713aSLionel Sambuc
testMallocWithParam_2(int ** p)1523f4a2713aSLionel Sambuc void testMallocWithParam_2(int **p) {
1524f4a2713aSLionel Sambuc *p = (int*) malloc(sizeof(int)); // no-warning
1525f4a2713aSLionel Sambuc }
1526f4a2713aSLionel Sambuc
testPassToSystemHeaderFunctionIndirectly()1527f4a2713aSLionel Sambuc void testPassToSystemHeaderFunctionIndirectly() {
1528f4a2713aSLionel Sambuc int *p = malloc(4);
1529f4a2713aSLionel Sambuc p++;
1530f4a2713aSLionel Sambuc fakeSystemHeaderCallInt(p);
1531f4a2713aSLionel Sambuc // FIXME: This is a leak: if we think a system function won't free p, it
1532f4a2713aSLionel Sambuc // won't free (p-1) either.
1533f4a2713aSLionel Sambuc }
1534