| /* PR ????? - No warning on attempts to access free object |
| Verify that freeing unallocated objects referenced either directly |
| or through pointers is diagnosed. |
| { dg-do compile } |
| { dg-options "-O2 -Wall -Wfree-nonheap-object" } */ |
| |
| typedef __INTPTR_TYPE__ intptr_t; |
| typedef __SIZE_TYPE__ size_t; |
| |
| extern "C" |
| { |
| void free (void*); |
| extern void* malloc (size_t); |
| extern void* realloc (void *p, size_t); |
| } |
| |
| void sink (void*, ...); |
| #define sink(...) sink (0, __VA_ARGS__) |
| |
| extern char ecarr[]; |
| extern void* eparr[]; |
| |
| extern char *eptr; |
| |
| void* source (void); |
| |
| void nowarn_free (void *p, void **pp, size_t n, intptr_t iptr) |
| { |
| free (p); |
| |
| p = 0; |
| free (p); |
| |
| p = malloc (n); |
| sink (p); |
| free (p); |
| |
| p = malloc (n); |
| sink (p); |
| |
| p = realloc (p, n * 2); |
| sink (p); |
| free (p); |
| |
| free ((void*)iptr); |
| |
| p = source (); |
| free (p); |
| |
| p = source (); |
| p = (char*)p - 1; |
| free (p); |
| |
| free (*pp); |
| } |
| |
| void warn_free_extern_arr (void) |
| { |
| free (ecarr); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| |
| void warn_free_extern_arr_offset (int i) |
| { |
| char *p = ecarr + i; |
| free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| |
| |
| void warn_free_cstint (void) |
| { |
| void *p = (void*)1; |
| sink (p); |
| free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| |
| |
| void warn_free_func (void) |
| { |
| void *p = (void*)warn_free_func; |
| sink (p); |
| free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| |
| |
| void warn_free_string (int i) |
| { |
| { |
| char *p = (char*)"123"; |
| sink (p); |
| free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| { |
| char *p = (char*)"234" + 1; |
| sink (p); |
| free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| { |
| char *p = (char*)"345" + i; |
| sink (p); |
| free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| |
| if (i >= 0) |
| { |
| char *p = (char*)"456" + i; |
| sink (p); |
| free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| } |
| |
| void warn_free_local_arr (int i) |
| { |
| { |
| char a[4]; |
| sink (a); |
| free (a); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| { |
| char b[5]; |
| sink (b); |
| |
| char *p = b + 1; |
| free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| { |
| char c[6]; |
| sink (c); |
| |
| char *p = c + i; |
| free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| } |
| |
| |
| void warn_free_vla (int n, int i) |
| { |
| { |
| int vla[n], *p = vla; |
| sink (p); |
| free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| |
| { |
| int vla[n + 1], *p = vla + 1; |
| sink (p); |
| free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| { |
| int vla[n + 2], *p = vla + i; |
| sink (p); |
| free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| } |
| |
| |
| void nowarn_free_extern_ptrarr (void) |
| { |
| free (*eparr); |
| } |
| |
| void nowarn_free_extern_ptrarr_offset (int i) |
| { |
| void *p = eparr[i]; |
| free (p); |
| } |
| |
| |
| void warn_free_extern_ptrarr (void) |
| { |
| free (eparr); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| |
| void warn_free_extern_ptrarr_offset (int i) |
| { |
| void *p = &eparr[i]; |
| free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| |
| |
| void nowarn_free_local_ptrarr (int i) |
| { |
| void* a[4]; |
| sink (a); |
| free (a[0]); |
| free (a[1]); |
| free (a[i]); |
| } |
| |
| |
| void nowarn_free_extern_ptr (void) |
| { |
| free (eptr); |
| } |
| |
| void nowarn_free_extern_ptr_offset (int i) |
| { |
| char *p = eptr + i; |
| free (p); |
| } |
| |
| void warn_free_extern_ptr_pos_offset (int i) |
| { |
| if (i <= 0) |
| i = 1; |
| |
| char *q = eptr + i; |
| free (q); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| |
| |
| void nowarn_free_parm_offset (char *p, int i) |
| { |
| char *q = p + i; |
| free (q); |
| } |
| |
| void nowarn_free_parm_neg_offset (char *p, int i) |
| { |
| if (i >= 0) |
| i = -1; |
| |
| char *q = p + i; |
| free (q); |
| } |
| |
| void warn_free_parm_pos_offset (char *p, int i) |
| { |
| if (i <= 0) |
| i = 1; |
| |
| char *q = p + i; |
| free (q); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| |
| |
| struct Members |
| { |
| char a[4], *p, *q; |
| }; |
| |
| extern struct Members em; |
| |
| void nowarn_free_member_ptr (struct Members *pm, int i) |
| { |
| char *p = em.p; |
| free (p); |
| p = em.q + i; |
| free (p); |
| |
| free (pm->q); |
| p = pm->p; |
| free (pm); |
| free (p); |
| } |
| |
| void nowarn_free_struct_cast (intptr_t *p) |
| { |
| struct Members *q = (struct Members*)*p; |
| if (q->p == 0) |
| free (q); // { dg-bogus "\\\[-Wfree-nonheap-object" } |
| } |
| |
| |
| void warn_free_member_array (void) |
| { |
| char *p = em.a; |
| free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |
| |
| void warn_free_member_array_off (int i) |
| { |
| char *p = em.a + i; |
| free (p); // { dg-warning "\\\[-Wfree-nonheap-object" } |
| } |