]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/testsuite/c-c++-common/Wuse-after-free-7.c
Add -Wuse-after-free [PR80532].
[thirdparty/gcc.git] / gcc / testsuite / c-c++-common / Wuse-after-free-7.c
1 /* Verify -Wuse-after-free=3 triggers for conditional and unconditional
2 uses in all expressions including equality.
3 { dg-do compile }
4 { dg-options "-O0 -Wall -Wuse-after-free=3" } */
5
6
7 #if __cplusplus
8 # define EXTERN_C extern "C"
9 #else
10 # define EXTERN_C extern
11 #endif
12
13 EXTERN_C void free (void*);
14
15 void sink (void*);
16
17
18 void warn_double_free (void *p)
19 {
20 free (p);
21 free (p); // { dg-warning "pointer 'p' used" }
22 }
23
24 void warn_cond_double_free (void *p, int c)
25 {
26 free (p);
27 if (c)
28 free (p); // { dg-warning "pointer 'p' may be used" }
29 }
30
31 void warn_call_after_free (void *p)
32 {
33 free (p);
34 sink (p); // { dg-warning "pointer 'p' used" }
35 }
36
37 void warn_cond_call_after_free (void *p, int c)
38 {
39 free (p);
40 if (c)
41 sink (p); // { dg-warning "pointer 'p' may be used" }
42 }
43
44 void* warn_return_after_free (void *p)
45 {
46 free (p);
47 return p; // { dg-warning "pointer 'p' used" }
48 }
49
50 void* warn_cond_return_after_free (void *p, int c)
51 {
52 free (p);
53 if (c)
54 return p; // { dg-warning "pointer 'p' may be used" }
55 return 0;
56 }
57
58 void warn_relational_after_free (char *p, char *q[])
59 {
60 free (p);
61
62 int a[] =
63 {
64 p < q[0], // { dg-warning "pointer 'p' used" }
65 p <= q[1], // { dg-warning "pointer 'p' used" }
66 p > q[2], // { dg-warning "pointer 'p' used" }
67 p >= q[3], // { dg-warning "pointer 'p' used" }
68 p == q[4], // { dg-warning "pointer 'p' used" }
69 p != q[5] // { dg-warning "pointer 'p' used" }
70 };
71
72 sink (a);
73 }
74
75 void warn_cond_relational_after_free (char *p, char *q[], int c)
76 {
77 free (p);
78
79 int a[] =
80 {
81 c ? p < q[0] : q[0][0], // { dg-warning "pointer 'p' may be used" }
82 c ? p <= q[1] : q[1][1], // { dg-warning "pointer 'p' may be used" }
83 c ? p > q[2] : q[2][2], // { dg-warning "pointer 'p' may be used" }
84 c ? p >= q[3] : q[3][3], // { dg-warning "pointer 'p' may be used" }
85 c ? p == q[4] : q[4][4], // { dg-warning "pointer 'p' may be used" }
86 c ? p != q[5] : q[5][5], // { dg-warning "pointer 'p' may be used" }
87 };
88
89 sink (a);
90 }
91
92
93 // Verify warning for the example in the manual.
94
95 struct A { int refcount; void *data; };
96
97 void release (struct A *p)
98 {
99 int refcount = --p->refcount;
100 free (p);
101 if (refcount == 0)
102 free (p->data); // { dg-warning "pointer 'p' may be used" }
103 }