1 /* Exercise basic cases of -Wuse-after-free without optimization.
3 { dg-options "-O0 -Wall" } */
5 typedef __SIZE_TYPE__
size_t;
8 # define EXTERN_C extern "C"
10 # define EXTERN_C extern
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*);
28 struct List
{ struct List
*next
; };
30 void nowarn_free (void *vp
, struct List
*lp
)
60 struct List
*next
= lp
->next
;
66 void nowarn_free_arg (void *p
, void *q
)
73 void nowarn_free_extern (void)
81 void nowarn_free_assign (void)
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
)
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
;
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
)
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" }