blob: ff3bddbce3597f15c80a83917799211d93b4b64e [file] [log] [blame]
// { dg-do compile }
// { dg-options "-O1" }
// { dg-final { scan-assembler-not "abort" } }
typedef __SIZE_TYPE__ size_t;
extern "C" {
void abort ();
void* malloc (size_t);
}
struct UDClass {
static int n;
UDClass () { ++n; }
virtual ~UDClass () { --n; }
};
int UDClass::n;
struct POD {
char buf [sizeof (UDClass)];
};
enum { N = 123 };
#if defined (__arm__) && defined (__ARM_EABI__)
// On ARM EABI the cookie is always 8 bytes as per Section 3.2.2 of
// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0041d/IHI0041D_cppabi.pdf
static const size_t cookie_size = 8;
#else
// On all other targets, the cookie size is the size of size_t
// GCC, and ideally the C++ standard, should provide an API to
// retrieve this constant.)
static const size_t cookie_size = sizeof (size_t);
#endif
inline __attribute__ ((always_inline))
void* operator new[] (size_t n)
{
// Verify that array new is invoked with an argument large enough
// for the array and a size_t cookie to store the number of elements.
// (This holds for classes with user-defined types but not POD types).
if (n != N * sizeof (UDClass) + cookie_size) abort ();
return malloc (n);
}
inline __attribute__ ((always_inline))
void* operator new[] (size_t n, void *p)
{
// Verify that the default placement array new is invoked with
// an argument just large enough for the array (and no cookie),
// regardless of whether the type is a POD or class with a user
// defined ctor.
if (n != N * sizeof (UDClass)) abort ();
return p;
}
inline __attribute__ ((always_inline))
void* operator new[] (size_t n, POD *p)
{
// Verify that placement array new overload for a POD type is
// invoked with an argument large enough for the array and
// a cookie.
if (n != N * sizeof (POD)) abort ();
return p;
}
inline __attribute__ ((always_inline))
void* operator new[] (size_t n, UDClass *p)
{
// Verify that placement array new overload for a class type with
// a user-defined ctor and dtor is invoked with an argument large
// enough for the array and a cookie.
if (n != N * sizeof (UDClass) + cookie_size) abort ();
return p;
}
// UDClassllocate a sufficiently large buffer to construct arrays into.
static unsigned char buf [N * N];
POD* test_new_POD ()
{
// Avoid testing PODs since for those, the global new is invoked
// without the overhead of a cookie.
// return new POD [N];
return 0;
}
POD* test_default_placement_new_POD ()
{
// Vefify that no overhead is allocated.
return new (buf) POD [N];
}
POD* test_overloaded_placement_new_POD ()
{
// Vefify that no overhead is allocated.
return new ((POD*)buf) POD [N];
}
UDClass* test_new_UDClass ()
{
// Vefify that space for a cookie is allocated.
return new UDClass [N];
}
UDClass* test_default_placement_new_UDClass ()
{
// Vefify that no overhead is allocated.
return new (buf) UDClass [N];
}
UDClass* test_overloaded_placement_new_UDClass ()
{
// Vefify that space for a cookie is allocated.
return new ((UDClass*)buf) UDClass [N];
}