// { dg-do run }
|
// { dg-do run }
|
#include
|
#include
|
|
|
void *p;
|
void *p;
|
int fail;
|
int fail;
|
|
|
class HeapTracked {
|
class HeapTracked {
|
public:
|
public:
|
virtual ~HeapTracked() = 0;
|
virtual ~HeapTracked() = 0;
|
void *operator new(size_t size);
|
void *operator new(size_t size);
|
void operator delete(void *ptr);
|
void operator delete(void *ptr);
|
static bool isObjectAllocation(const HeapTracked *ptr);
|
static bool isObjectAllocation(const HeapTracked *ptr);
|
};
|
};
|
|
|
HeapTracked::~HeapTracked(){}
|
HeapTracked::~HeapTracked(){}
|
void * HeapTracked::operator new(size_t size)
|
void * HeapTracked::operator new(size_t size)
|
{
|
{
|
void * memPtr = ::operator new(size);
|
void * memPtr = ::operator new(size);
|
p = memPtr;
|
p = memPtr;
|
return memPtr;
|
return memPtr;
|
}
|
}
|
|
|
void HeapTracked::operator delete(void *ptr)
|
void HeapTracked::operator delete(void *ptr)
|
{
|
{
|
if (p != ptr)
|
if (p != ptr)
|
fail = 1;
|
fail = 1;
|
::operator delete(ptr);
|
::operator delete(ptr);
|
}
|
}
|
|
|
bool HeapTracked::isObjectAllocation(const HeapTracked *ptr)
|
bool HeapTracked::isObjectAllocation(const HeapTracked *ptr)
|
{
|
{
|
if (p != const_cast(dynamic_cast(ptr)))
|
if (p != const_cast(dynamic_cast(ptr)))
|
fail = 1;
|
fail = 1;
|
return false;
|
return false;
|
}
|
}
|
|
|
class Mumble1: public virtual HeapTracked {
|
class Mumble1: public virtual HeapTracked {
|
double d;
|
double d;
|
public:
|
public:
|
virtual ~Mumble1(){}
|
virtual ~Mumble1(){}
|
};
|
};
|
|
|
class Mumble2: public virtual HeapTracked {
|
class Mumble2: public virtual HeapTracked {
|
double d;
|
double d;
|
public:
|
public:
|
virtual ~Mumble2(){}
|
virtual ~Mumble2(){}
|
};
|
};
|
|
|
class Foo: virtual public HeapTracked,
|
class Foo: virtual public HeapTracked,
|
virtual public Mumble1,
|
virtual public Mumble1,
|
virtual public Mumble2 {
|
virtual public Mumble2 {
|
public:
|
public:
|
~Foo(){}
|
~Foo(){}
|
};
|
};
|
|
|
int main()
|
int main()
|
{
|
{
|
Foo *pf = new Foo;
|
Foo *pf = new Foo;
|
pf->isObjectAllocation(pf);
|
pf->isObjectAllocation(pf);
|
|
|
Mumble1 *pm1 = pf;
|
Mumble1 *pm1 = pf;
|
pm1->isObjectAllocation(pm1);
|
pm1->isObjectAllocation(pm1);
|
|
|
Mumble2 *pm2 = pf;
|
Mumble2 *pm2 = pf;
|
pm2->isObjectAllocation(pm2);
|
pm2->isObjectAllocation(pm2);
|
|
|
// delete pf;
|
// delete pf;
|
// delete pm1;
|
// delete pm1;
|
delete pm2;
|
delete pm2;
|
|
|
return fail;
|
return fail;
|
}
|
}
|
|
|