1 /* PR ????? - No warning on attempts to access free object
2 Verify that freeing unallocated objects referenced either directly
3 or through pointers is diagnosed. In most cases this doesn't require
4 optimization.
5 { dg-do compile }
6 { dg-options "-Wall -Wfree-nonheap-object" }
7 { dg-require-effective-target alloca } */
8
9 typedef __INTPTR_TYPE__ intptr_t;
10 typedef __SIZE_TYPE__ size_t;
11
12 extern void free (void*);
13 extern void* malloc (size_t);
14 extern void* realloc (void *p, size_t);
15
16 void sink (void*, ...);
17
18 extern char ecarr[];
19 extern void* eparr[];
20
21 extern char *eptr;
22
23 void* source (void);
24
25 void nowarn_free (void *p, void **pp, size_t n, intptr_t iptr)
26 {
27 free (p);
28
29 p = 0;
30 free (p);
31
32 p = malloc (n);
33 sink (p);
34 free (p);
35
36 p = malloc (n);
37 sink (p);
38
39 p = realloc (p, n * 2);
40 sink (p);
41 free (p);
42
43 free ((void*)iptr);
44
45 p = source ();
46 free (p);
47
48 p = source ();
49 p = (char*)p - 1;
50 free (p);
51
52 free (*pp);
53 }
54
55 void warn_free_extern_arr (void)
56 {
57 free (ecarr); // { dg-warning "\\\[-Wfree-nonheap-object" }
58 }
59
60 void warn_free_extern_arr_offset (int i)
61 {
62 char *p = ecarr + i;
63 free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
64 }
65
66
67 void warn_free_cstint (void)
68 {
69 void *p = (void*)1;
70 sink (p);
71 free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
72 }
73
74
75 void warn_free_func (void)
76 {
77 void *p = warn_free_func;
78 sink (p);
79 free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
80 }
81
82
83 void warn_free_string (int i)
84 {
85 {
86 char *p = "123";
87 sink (p);
88 free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
89 }
90 {
91 char *p = "234" + 1;
92 sink (p);
93 free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
94 }
95 {
96 char *p = "345" + i;
97 sink (p);
98 free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
99 }
100
101 if (i >= 0)
102 {
103 char *p = "456" + i;
104 sink (p);
105 free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
106 }
107 }
108
109 void warn_free_local_arr (int i)
110 {
111 {
112 char a[4];
113 sink (a);
114 free (a); // { dg-warning "\\\[-Wfree-nonheap-object" }
115 }
116 {
117 char b[5];
118 sink (b);
119
120 char *p = b + 1;
121 free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
122 }
123 {
124 char c[6];
125 sink (c);
126
127 char *p = c + i;
128 free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
129 }
130 }
131
132
133 void warn_free_vla (int n, int i)
134 {
135 {
136 int vla[n], *p = vla;
137 sink (p);
138 free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
139 }
140
141 {
142 int vla[n + 1], *p = vla + 1;
143 sink (p);
144 free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
145 }
146 {
147 int vla[n + 2], *p = vla + i;
148 sink (p);
149 free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
150 }
151 }
152
153
154 void nowarn_free_extern_ptrarr (void)
155 {
156 free (*eparr);
157 }
158
159 void nowarn_free_extern_ptrarr_offset (int i)
160 {
161 char *p = eparr[i];
162 free (p);
163 }
164
165
166 void warn_free_extern_ptrarr (void)
167 {
168 free (eparr); // { dg-warning "\\\[-Wfree-nonheap-object" }
169 }
170
171 void warn_free_extern_ptrarr_offset (int i)
172 {
173 void *p = &eparr[i];
174 free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
175 }
176
177
178 void nowarn_free_local_ptrarr (int i)
179 {
180 void* a[4];
181 sink (a);
182 free (a[0]);
183 free (a[1]);
184 free (a[i]);
185 }
186
187
188 void nowarn_free_extern_ptr (void)
189 {
190 free (eptr);
191 }
192
193 void nowarn_free_extern_ptr_offset (int i)
194 {
195 char *p = eptr + i;
196 free (p);
197 }
198
199 void nowarn_free_parm_offset (char *p, int i)
200 {
201 char *q = p + i;
202 free (q);
203 }
204
205 void nowarn_free_parm_neg_offset (char *p, int i)
206 {
207 if (i >= 0)
208 i = -1;
209
210 char *q = p + i;
211 free (q);
212 }
213
214 struct Members
215 {
216 char a[4], *p, *q;
217 };
218
219 extern struct Members em;
220
221 void nowarn_free_member_ptr (struct Members *pm, int i)
222 {
223 char *p = em.p;
224 free (p);
225 p = em.q + i;
226 free (p);
227
228 free (pm->q);
229 p = pm->p;
230 free (pm);
231 free (p);
232 }
233
234 void nowarn_free_struct_cast (intptr_t *p)
235 {
236 struct Members *q = (struct Members*)*p;
237 if (q->p == 0)
238 free (q); // { dg-bogus "\\\[-Wfree-nonheap-object" }
239 }
240
241
242 void warn_free_member_array (void)
243 {
244 char *p = em.a;
245 free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
246 }
247
248 void warn_free_member_array_off (int i)
249 {
250 char *p = em.a + i;
251 free (p); // { dg-warning "\\\[-Wfree-nonheap-object" }
252 }
253
254
255 // Range information requires optimization.
256 #pragma GCC optimize "1"
257
258 void warn_free_extern_ptr_pos_offset (int i)
259 {
260 if (i <= 0)
261 i = 1;
262
263 char *q = eptr + i;
264 free (q); // { dg-warning "\\\[-Wfree-nonheap-object" }
265 }
266
267 void warn_free_parm_pos_offset (char *p, int i)
268 {
269 if (i <= 0)
270 i = 1;
271
272 char *q = p + i;
273 free (q); // { dg-warning "\\\[-Wfree-nonheap-object" }
274 }