blob: fc07149995de4bc6671310d204cc351013922926 [file] [log] [blame]
/* PR c++/90629 - Support for -Wmismatched-new-delete
The detection doesn't require optimization.
{ dg-do compile }
{ dg-options "-Wall" } */
typedef __SIZE_TYPE__ size_t;
extern "C" {
void free (void *);
void* malloc (size_t);
void* realloc (void *, size_t);
char* strdup (const char *);
char* strndup (const char *, size_t);
}
void sink (void *);
void nowarn_op_new_delete (int n)
{
void *p = operator new (n);
sink (p);
operator delete (p);
}
void nowarn_new_delete (int n)
{
{
char *p = new char;
sink (p);
delete p;
}
{
char *p = new char[n];
sink (p);
delete[] p;
}
}
/* Verify a warning for calls to free() with a pointer returned from
a call to operator new() or the new expressopm. */
void warn_new_free (int n)
{
{
void *p = operator new (n);
// { dg-message "returned from 'void\\\* operator new\\\(" "note" { target *-*-* } .-1 }
sink (p);
free (p);
// { dg-warning "'void free\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 }
}
{
char *p = new char[n];
// { dg-message "returned from 'void\\\* operator new \\\[" "note" { target *-*-* } .-1 }
sink (p);
free (p);
// { dg-warning "'void free\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 }
}
}
/* Verify a warning for calls to realloc() with a pointer returned from
a call to operator new() or the new expressopm. */
void warn_new_realloc (int n)
{
{
void *p = operator new (n);
// { dg-message "returned from 'void\\\* operator new\\\(" "note" { target *-*-* } .-1 }
sink (p);
p = realloc (p, n * 2);
// { dg-warning "'void\\\* realloc\\\(\[^)\]+\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 }
sink (p);
}
{
void *p = new char[n];
// { dg-message "returned from 'void\\\* operator new \\\[" "note" { target *-*-* } .-1 }
sink (p);
p = realloc (p, n * 2);
// { dg-warning "'void\\\* realloc\\\(\[^)\]+\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 }
sink (p);
}
}
/* Verify a warning for a call to operator_delete() with a pointer returned
from a call to malloc(). */
void warn_malloc_op_delete (int n)
{
char *p = (char *)malloc (n);
// { dg-message "returned from 'void\\\* malloc\\\(" "note" { target *-*-* } .-1 }
sink (p);
operator delete (p);
// { dg-warning "'void operator delete\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 }
}
/* Verify a warning for an invocation of either form of the delete
expression with a pointer returned from malloc(). */
void warn_malloc_delete (int n)
{
{
char *p = (char *)malloc (n);
// { dg-message "returned from 'void\\\* malloc\\\(" "note" { target *-*-* } .-1 }
sink (p);
/* C++98 calls operator delete (void*) but later versions call
operator delete (void*, size_t). The difference doesn't matter
here so verify just that some operator delete is called. */
delete p;
// { dg-warning "'void operator delete\\\(\[^)\]+\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 }
}
{
char *p = (char *)malloc (n);
// { dg-message "returned from 'void\\\* malloc\\\(" "note" { target *-*-* } .-1 }
sink (p);
delete[] p;
// { dg-warning "'void operator delete \\\[]\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 }
}
}
/* Verify a warning for an invocation of either form of the delete
expression with a pointer returned from realloc(). */
void warn_realloc_delete (void *p1, void *p2, int n)
{
{
char *q = (char *)realloc (p1, n);
// { dg-message "returned from 'void\\\* realloc\\\(" "note" { target *-*-* } .-1 }
sink (q);
/* C++98 calls operator delete (void*) but later versions call
operator delete (void*, size_t). The difference doesn't matter
here so verify just that some operator delete is called. */
delete q;
// { dg-warning "'void operator delete\\\(\[^)\]+\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 }
}
{
char *q = (char *)realloc (p2, n);
// { dg-message "returned from 'void\\\* realloc\\\(" "note" { target *-*-* } .-1 }
sink (q);
delete[] q;
// { dg-warning "'void operator delete \\\[]\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 }
}
}
/* Verify a warning for an invocation of either form of the delete
expression with a pointer returned from strdup(). */
void warn_strdup_delete (const char *s1, const char *s2)
{
{
char *q = strdup (s1);
// { dg-message "returned from 'char\\\* strdup\\\(" "note" { target *-*-* } .-1 }
sink (q);
/* C++98 calls operator delete (void*) but later versions call
operator delete (void*, size_t). The difference doesn't matter
here so verify just that some operator delete is called. */
delete q;
// { dg-warning "'void operator delete\\\(\[^)\]+\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 }
}
{
char *q = strdup (s2);
// { dg-message "returned from 'char\\\* strdup\\\(" "note" { target *-*-* } .-1 }
sink (q);
delete[] q;
// { dg-warning "'void operator delete \\\[]\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 }
}
}
/* Verify a warning for an invocation of either form of the delete
expression with a pointer returned from strndup(). */
void warn_strdup_delete (const char *s1, const char *s2, size_t n)
{
{
char *q = strndup (s1, n);
// { dg-message "returned from 'char\\\* strndup\\\(" "note" { target *-*-* } .-1 }
sink (q);
/* C++98 calls operator delete (void*) but later versions call
operator delete (void*, size_t). The difference doesn't matter
here so verify just that some operator delete is called. */
delete q;
// { dg-warning "'void operator delete\\\(\[^)\]+\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 }
}
{
char *q = strndup (s2, n);
// { dg-message "returned from 'char\\\* strndup\\\(" "note" { target *-*-* } .-1 }
sink (q);
delete[] q;
// { dg-warning "'void operator delete \\\[]\\\(void\\\*\\\)' called on pointer returned from a mismatched allocation function" "" { target *-*-* } .-1 }
}
}
struct Base { virtual ~Base (); };
struct Derived: Base { };
void warn_new_free_base_derived ()
{
Base *p = new Derived ();
sink (p);
free (p); // { dg-warning "\\\[-Wmismatched-new-delete" }
}