(root)/
gcc-13.2.0/
gcc/
testsuite/
g++.dg/
warn/
Wfree-nonheap-object.C
/* 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+]" }
}