| // { 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]; |
| } |