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