]>
Commit | Line | Data |
---|---|---|
dce6c58d MS |
1 | /* PR middle-end/94527 - Add an attribute that marks a function as freeing |
2 | an object | |
3 | Verify that attribute malloc with one or two arguments has the expected | |
4 | effect on diagnostics. | |
5 | { dg-options "-Wall -ftrack-macro-expansion=0" } */ | |
6 | ||
7 | #define A(...) __attribute__ ((malloc (__VA_ARGS__))) | |
8 | ||
9 | typedef struct FILE FILE; | |
10 | typedef __SIZE_TYPE__ size_t; | |
11 | ||
12 | void free (void*); | |
13 | void* malloc (size_t); | |
14 | void* realloc (void*, size_t); | |
15 | ||
fe7f75cf MS |
16 | /* Declare functions with the minimum attributes malloc how they're |
17 | likely going to be declared in <stdio.h>. */ | |
18 | int fclose (FILE*); | |
19 | A (fclose) FILE* fdopen (int); | |
20 | A (fclose) FILE* fopen (const char*, const char*); | |
21 | A (fclose) FILE* fmemopen(void *, size_t, const char *); | |
22 | A (fclose) FILE* freopen (const char*, const char*, FILE*); | |
23 | A (freopen, 3) FILE* freopen (const char*, const char*, FILE*); | |
24 | A (fclose) FILE* tmpfile (void); | |
dce6c58d | 25 | |
fe7f75cf MS |
26 | A (fclose) FILE* open_memstream (char**, size_t*); |
27 | A (fclose) FILE* open_wmemstream (char**, size_t*); | |
28 | ||
29 | int pclose (FILE*); | |
30 | A (pclose) FILE* popen (const char*, const char*); | |
dce6c58d | 31 | |
fe7f75cf MS |
32 | void release (void*); |
33 | A (release) FILE* acquire (void); | |
34 | ||
35 | void sink (FILE*); | |
dce6c58d | 36 | |
dce6c58d MS |
37 | |
38 | void nowarn_fdopen (void) | |
39 | { | |
40 | { | |
41 | FILE *q = fdopen (0); | |
42 | if (!q) | |
43 | return; | |
44 | ||
45 | fclose (q); | |
46 | } | |
47 | ||
48 | { | |
49 | FILE *q = fdopen (0); | |
50 | if (!q) | |
51 | return; | |
52 | ||
53 | q = freopen ("1", "r", q); | |
54 | fclose (q); | |
55 | } | |
56 | ||
57 | { | |
58 | FILE *q = fdopen (0); | |
59 | if (!q) | |
60 | return; | |
61 | ||
62 | sink (q); | |
63 | } | |
64 | } | |
65 | ||
66 | ||
67 | void warn_fdopen (void) | |
68 | { | |
69 | { | |
fe7f75cf | 70 | FILE *q = fdopen (0); // { dg-message "returned from 'fdopen'" "note" } |
dce6c58d MS |
71 | sink (q); |
72 | release (q); // { dg-warning "'release' called on pointer returned from a mismatched allocation function" } | |
73 | } | |
74 | { | |
fe7f75cf | 75 | FILE *q = fdopen (0); // { dg-message "returned from 'fdopen'" "note" } |
dce6c58d MS |
76 | sink (q); |
77 | free (q); // { dg-warning "'free' called on pointer returned from a mismatched allocation function" } | |
78 | } | |
79 | ||
80 | { | |
fe7f75cf | 81 | FILE *q = fdopen (0); // { dg-message "returned from 'fdopen'" "note" } |
dce6c58d MS |
82 | sink (q); |
83 | q = realloc (q, 7); // { dg-warning "'realloc' called on pointer returned from a mismatched allocation function" } | |
84 | sink (q); | |
85 | } | |
86 | } | |
87 | ||
88 | ||
89 | void nowarn_fopen (void) | |
90 | { | |
91 | { | |
92 | FILE *q = fopen ("1", "r"); | |
93 | sink (q); | |
94 | fclose (q); | |
95 | } | |
96 | ||
97 | { | |
98 | FILE *q = fopen ("2", "r"); | |
99 | sink (q); | |
100 | q = freopen ("3", "r", q); | |
101 | sink (q); | |
102 | fclose (q); | |
103 | } | |
104 | ||
105 | { | |
106 | FILE *q = fopen ("4", "r"); | |
107 | sink (q); | |
108 | } | |
109 | } | |
110 | ||
111 | ||
112 | void warn_fopen (void) | |
113 | { | |
114 | { | |
115 | FILE *q = fopen ("1", "r"); | |
116 | sink (q); | |
117 | release (q); // { dg-warning "'release' called on pointer returned from a mismatched allocation function" } | |
118 | } | |
119 | { | |
120 | FILE *q = fdopen (0); | |
121 | sink (q); | |
122 | free (q); // { dg-warning "'free' called on pointer returned from a mismatched allocation function" } | |
123 | } | |
124 | ||
125 | { | |
126 | FILE *q = fdopen (0); | |
127 | sink (q); | |
128 | q = realloc (q, 7); // { dg-warning "'realloc' called on pointer returned from a mismatched allocation function" } | |
129 | sink (q); | |
130 | } | |
131 | } | |
132 | ||
133 | ||
fe7f75cf | 134 | void test_freopen (FILE *p[]) |
dce6c58d MS |
135 | { |
136 | { | |
fe7f75cf MS |
137 | FILE *q = freopen ("1", "r", p[0]); |
138 | sink (q); | |
139 | fclose (q); | |
140 | } | |
141 | { | |
142 | FILE *q = freopen ("2", "r", p[1]); | |
143 | sink (q); | |
144 | q = freopen ("3", "r", q); | |
145 | sink (q); | |
146 | fclose (q); | |
147 | } | |
148 | ||
149 | { | |
150 | FILE *q; | |
151 | q = freopen ("3", "r", p[2]); // { dg-message "returned from 'freopen'" } | |
152 | sink (q); | |
153 | q = realloc (q, 7); // { dg-warning "'realloc' called on pointer returned from a mismatched allocation function" } | |
154 | sink (q); | |
155 | } | |
156 | } | |
157 | ||
158 | ||
159 | void test_tmpfile (void) | |
160 | { | |
161 | { | |
162 | FILE *p = tmpfile (); | |
dce6c58d | 163 | sink (p); |
fe7f75cf | 164 | fclose (p); |
dce6c58d MS |
165 | } |
166 | ||
167 | { | |
fe7f75cf | 168 | FILE *p = tmpfile (); |
dce6c58d | 169 | sink (p); |
fe7f75cf MS |
170 | p = freopen ("1", "r", p); |
171 | sink (p); | |
172 | fclose (p); | |
dce6c58d MS |
173 | } |
174 | ||
175 | { | |
fe7f75cf | 176 | FILE *p = tmpfile (); // { dg-message "returned from 'tmpfile'" "note" } |
dce6c58d | 177 | sink (p); |
fe7f75cf MS |
178 | pclose (p); // { dg-warning "'pclose' called on pointer returned from a mismatched allocation function" } |
179 | } | |
180 | } | |
181 | ||
182 | ||
183 | void test_open_memstream (char **bufp, size_t *sizep) | |
184 | { | |
185 | { | |
186 | FILE *p = open_memstream (bufp, sizep); | |
187 | sink (p); | |
188 | fclose (p); | |
189 | } | |
190 | ||
191 | { | |
192 | FILE *p = open_memstream (bufp, sizep); | |
193 | sink (p); | |
194 | p = freopen ("1", "r", p); | |
195 | sink (p); | |
196 | fclose (p); | |
197 | } | |
198 | ||
199 | { | |
200 | FILE *p; | |
201 | p = open_memstream (bufp, sizep); // { dg-message "returned from 'open_memstream'" "note" } | |
dce6c58d MS |
202 | sink (p); |
203 | pclose (p); // { dg-warning "'pclose' called on pointer returned from a mismatched allocation function" } | |
204 | } | |
fe7f75cf MS |
205 | |
206 | { | |
207 | FILE *p; | |
208 | p = open_memstream (bufp, sizep); // { dg-message "returned from 'open_memstream'" "note" } | |
209 | sink (p); | |
210 | free (p); // { dg-warning "'free' called on pointer returned from a mismatched allocation function" } | |
211 | } | |
212 | ||
213 | { | |
214 | FILE *p; | |
215 | p = open_memstream (bufp, sizep); // { dg-message "returned from 'open_memstream'" "note" } | |
216 | sink (p); | |
217 | release (p); // { dg-warning "'release' called on pointer returned from a mismatched allocation function" } | |
218 | } | |
dce6c58d MS |
219 | } |
220 | ||
221 | ||
fe7f75cf | 222 | void test_open_wmemstream (char **bufp, size_t *sizep) |
dce6c58d MS |
223 | { |
224 | { | |
fe7f75cf | 225 | FILE *p = open_wmemstream (bufp, sizep); |
dce6c58d MS |
226 | sink (p); |
227 | fclose (p); | |
228 | } | |
229 | ||
230 | { | |
fe7f75cf | 231 | FILE *p = open_wmemstream (bufp, sizep); |
dce6c58d MS |
232 | sink (p); |
233 | p = freopen ("1", "r", p); | |
234 | sink (p); | |
235 | fclose (p); | |
236 | } | |
237 | ||
238 | { | |
fe7f75cf MS |
239 | FILE *p; |
240 | p = open_wmemstream (bufp, sizep); // { dg-message "returned from 'open_wmemstream'" "note" } | |
dce6c58d MS |
241 | sink (p); |
242 | pclose (p); // { dg-warning "'pclose' called on pointer returned from a mismatched allocation function" } | |
243 | } | |
fe7f75cf MS |
244 | |
245 | { | |
246 | FILE *p; | |
247 | p = open_wmemstream (bufp, sizep); // { dg-message "returned from 'open_wmemstream'" "note" } | |
248 | sink (p); | |
249 | free (p); // { dg-warning "'free' called on pointer returned from a mismatched allocation function" } | |
250 | } | |
251 | ||
252 | { | |
253 | FILE *p; | |
254 | p = open_wmemstream (bufp, sizep); // { dg-message "returned from 'open_wmemstream'" "note" } | |
255 | sink (p); | |
256 | release (p); // { dg-warning "'release' called on pointer returned from a mismatched allocation function" } | |
257 | } | |
dce6c58d MS |
258 | } |
259 | ||
260 | ||
261 | void warn_malloc (void) | |
262 | { | |
263 | { | |
fe7f75cf | 264 | FILE *p = malloc (100); // { dg-message "returned from 'malloc'" "note" } |
dce6c58d MS |
265 | sink (p); |
266 | fclose (p); // { dg-warning "'fclose' called on pointer returned from a mismatched allocation function" } | |
267 | } | |
268 | ||
269 | { | |
fe7f75cf | 270 | FILE *p = malloc (100); // { dg-message "returned from 'malloc'" "note" } |
dce6c58d MS |
271 | sink (p); |
272 | p = freopen ("1", "r", p);// { dg-warning "'freopen' called on pointer returned from a mismatched allocation function" } | |
273 | } | |
274 | ||
275 | { | |
fe7f75cf | 276 | FILE *p = malloc (100); // { dg-message "returned from 'malloc'" "note" } |
dce6c58d MS |
277 | sink (p); |
278 | pclose (p); // { dg-warning "'pclose' called on pointer returned from a mismatched allocation function" } | |
279 | } | |
280 | } | |
281 | ||
282 | ||
283 | void test_acquire (void) | |
284 | { | |
285 | { | |
286 | FILE *p = acquire (); | |
287 | release (p); | |
288 | } | |
289 | ||
290 | { | |
291 | FILE *p = acquire (); | |
292 | sink (p); | |
293 | release (p); | |
294 | } | |
295 | ||
296 | { | |
fe7f75cf | 297 | FILE *p = acquire (); // { dg-message "returned from 'acquire'" "note" } |
dce6c58d MS |
298 | sink (p); |
299 | fclose (p); // { dg-warning "'fclose' called on pointer returned from a mismatched allocation function" } | |
300 | } | |
301 | ||
302 | { | |
fe7f75cf | 303 | FILE *p = acquire (); // { dg-message "returned from 'acquire'" "note" } |
dce6c58d MS |
304 | sink (p); |
305 | pclose (p); // { dg-warning "'pclose' called on pointer returned from a mismatched allocation function" } | |
306 | } | |
307 | ||
308 | { | |
fe7f75cf | 309 | FILE *p = acquire (); // { dg-message "returned from 'acquire'" "note" } |
dce6c58d MS |
310 | sink (p); |
311 | p = freopen ("1", "r", p); // { dg-warning "'freopen' called on pointer returned from a mismatched allocation function" } | |
312 | sink (p); | |
313 | } | |
314 | ||
315 | { | |
fe7f75cf | 316 | FILE *p = acquire (); // { dg-message "returned from 'acquire'" "note" } |
dce6c58d MS |
317 | sink (p); |
318 | free (p); // { dg-warning "'free' called on pointer returned from a mismatched allocation function" } | |
319 | } | |
320 | ||
321 | { | |
fe7f75cf | 322 | FILE *p = acquire (); // { dg-message "returned from 'acquire'" "note" } |
dce6c58d MS |
323 | sink (p); |
324 | p = realloc (p, 123); // { dg-warning "'realloc' called on pointer returned from a mismatched allocation function" } | |
325 | sink (p); | |
326 | } | |
327 | } |