/* PR ????? - No warning on attempts to access free object Verify that attempts to deallocate objects by pointers with nonzero offsets is diagnosed. { dg-do compile } { dg-options "-O2 -Wall -Wfree-nonheap-object" } */ typedef __INTPTR_TYPE__ intptr_t; typedef __SIZE_TYPE__ size_t; void sink (void*, ...); extern char ecarr[]; extern void* eparr[]; extern char *eptr; char* source (void); void nowarn_op_delete (void *p, void ***ppp, size_t n, intptr_t iptr) { operator delete (p); p = 0; operator delete (p); p = operator new (n); sink (p); operator delete (p); p = operator new (n); sink (p); operator delete ((void*)iptr); p = source (); operator delete (p); p = source (); p = (char*)p - 1; operator delete (p); operator delete (**ppp); operator delete (*ppp); operator delete (ppp); } void warn_op_delete_cstaddr (void *p) { operator delete (p); p = (void*)~0; operator delete (p); // { dg-warning "called on a pointer to an unallocated object" } */ } void warn_op_delete_funcaddr () { void *p = (void*)&warn_op_delete_funcaddr; operator delete (p); // { dg-warning "called on unallocated object 'void warn_op_delete_funcaddr()" } */ } void warn_op_delete_string (void *p) { operator delete (p); p = (void*)""; operator delete (p); // { dg-warning "called on a pointer to an unallocated object" } */ } void warn_op_delete_ptr_to_self (void *p) { operator delete (p); p = &p; operator delete (p); // { dg-warning "called on unallocated object 'p'" } */ } void nowarn_op_new_delete (size_t n) { void *p = operator new (n); sink (p); operator delete (p); } void nowarn_op_new_delete_ptr_plus (size_t n) { void *p0_1 = operator new (n); void *p1 = (char*)p0_1 + 1; sink (p0_1, p1); void *p0_2 = (char*)p1 - 1; sink (p0_1, p1, p0_2); operator delete (p0_2); } void warn_op_new_delete_cstoff (size_t n) { void *p = operator new (n); void *q = (char*)p + 1; sink (p, q); operator delete (q); // { dg-warning "'void operator delete\\\(void\\\*\\\)' called on pointer '\[^'\]+' with nonzero offset 1" } } void warn_op_new_delete_ptr_plus (size_t n) { char *p = (char*)operator new (n); sink (++p); operator delete (p); // { dg-warning "called on pointer '\[^']+' with nonzero offset 1" } } void warn_op_delete_funcret_plus (size_t n) { char *p = source (); sink (++p); operator delete (p); // { dg-warning "called on pointer '\[^']+' with nonzero offset 1" } } void warn_op_delete_eptr_plus (int i) { extern char *ecp; if (i < 1) i = 1; char *p = ecp + i; sink (p); operator delete (p); // { dg-warning "called on pointer '\[^']+' with nonzero offset \\\[1, \\d+]" } }