c++: prvalue of array type [PR111286]
[official-gcc.git] / gcc / testsuite / c-c++-common / Wuse-after-free.c
blob634d3142f435493fb320639098d0cccb26430d9f
1 /* Exercise basic cases of -Wuse-after-free without optimization.
2 { dg-do compile }
3 { dg-options "-O0 -Wall" } */
5 typedef __SIZE_TYPE__ size_t;
7 #if __cplusplus
8 # define EXTERN_C extern "C"
9 #else
10 # define EXTERN_C extern
11 #endif
13 EXTERN_C void* alloca (size_t);
15 EXTERN_C void* calloc (size_t, size_t);
16 EXTERN_C void* malloc (size_t);
18 EXTERN_C void free (void*);
21 void sink (void *);
23 extern void* evp;
24 extern void* evpa[];
26 extern int ei;
28 struct List { struct List *next; };
30 void nowarn_free (void *vp, struct List *lp)
33 free (vp);
34 vp = 0;
35 sink (vp);
38 free (evp);
39 evp = 0;
40 sink (evp);
43 free (evpa[0]);
44 evpa[0] = 0;
45 sink (evpa[0]);
48 void *vp = evpa[0];
49 free (evpa[1]);
50 sink (vp);
53 void *p = evpa[1];
54 if (ei & 1)
55 free (p);
56 if (ei & 2)
57 sink (p);
60 struct List *next = lp->next;
61 free (lp);
62 free (next);
66 void nowarn_free_arg (void *p, void *q)
68 free (p);
69 if (q)
70 free (q);
73 void nowarn_free_extern (void)
75 extern void *ep, *eq;
76 free (ep);
77 ep = eq;
78 free (ep);
81 void nowarn_free_assign (void)
83 extern void *ep;
84 free (ep);
85 ep = 0;
86 free (ep);
89 #pragma GCC diagnostic push
90 /* Verify that -Wuse-after-free works with #pragma diagnostic. Note
91 that the option name should not need to include a trailing =, even
92 though it's a multi-level option. (specifying the level after
93 the option, as in "-Wuse-after-free=2", doesn't work. */
94 #pragma GCC diagnostic ignored "-Wuse-after-free"
96 void nowarn_double_free_suppressed (void *p)
98 free (p);
99 free (p);
102 #pragma GCC diagnostic pop
104 void warn_double_free_arg (void *p)
106 free (p); // { dg-message "call to '\(void \)?free\(\\(void\\*\\)\)?'" "note" }
107 // Verify exactly one warning is issued.
108 free (p); // { dg-warning "\\\-Wuse-after-free" }
109 // { dg-bogus "\\\-Wuse-after-free" "duplicate warning" { target *-*-* } .-1 }
113 void warn_double_free_extern (void)
115 /* GCC assumes free() clobbers global memory and the warning is
116 too simplistic to see through that assumption. */
117 extern void *ep, *eq;
119 eq = ep;
120 free (ep); // { dg-message "call to 'free'" "pr??????" { xfail *-*-* } }
121 free (eq); // { dg-warning "\\\-Wuse-after-free" "pr??????" { xfail *-*-* } }
125 void warn_deref_after_free (int *p, int i)
127 int *q0 = p, *q1 = p + 1, *qi = p + i;
128 free (p); // { dg-message "call to '\(void \)?free\(\\(void\\*\\)\)?'" "note" }
129 *p = 0; // { dg-warning "\\\-Wuse-after-free" }
131 *q0 = 0; // { dg-warning "\\\-Wuse-after-free" }
132 *q1 = 0; // { dg-warning "\\\-Wuse-after-free" }
133 *qi = 0; // { dg-warning "\\\-Wuse-after-free" }
136 void warn_array_ref_after_free (int *p, int i)
138 free (p); // { dg-message "call to '\(void \)?free\(\\(void\\*\\)\)?'" "note" }
139 p[i] = 0; // { dg-warning "\\\-Wuse-after-free" }
142 void nowarn_free_list (struct List *head)
144 for (struct List *p = head, *q; p; p = q)
146 q = p->next;
147 free (p);
151 void warn_free_list (struct List *head)
153 struct List *p = head;
154 for (; p; p = p->next) // { dg-warning "\\\[-Wuse-after-free" }
155 free (p); // { dg-message "call to '\(void \)?free\(\\(void\\*\\)\)?'" "note" }
159 void warn_free (void *vp)
162 free (vp); // { dg-message "call to '\(void \)?free\(\\(void\\*\\)\)?'" "note" }
163 evp = vp; // { dg-warning "-Wuse-after-free" }
164 evpa[0] = vp; // { dg-warning "-Wuse-after-free" }
165 evpa[1] = evp;