// { dg-do run }
|
// { dg-do run }
|
// Origin: Mark Mitchell
|
// Origin: Mark Mitchell
|
|
|
#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
|
#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
|
|
|
#include
|
#include
|
#include
|
#include
|
|
|
void* p;
|
void* p;
|
|
|
void* operator new[](size_t s) throw (std::bad_alloc)
|
void* operator new[](size_t s) throw (std::bad_alloc)
|
{
|
{
|
// Record the base of the last array allocated.
|
// Record the base of the last array allocated.
|
p = malloc (s);
|
p = malloc (s);
|
return p;
|
return p;
|
}
|
}
|
|
|
template
|
template
|
void check_no_cookie (int i)
|
void check_no_cookie (int i)
|
{
|
{
|
void* a = new T[7];
|
void* a = new T[7];
|
if (p != a)
|
if (p != a)
|
exit (i);
|
exit (i);
|
}
|
}
|
|
|
template
|
template
|
void check_no_placement_cookie (int i)
|
void check_no_placement_cookie (int i)
|
{
|
{
|
p = malloc (13 * sizeof (T));
|
p = malloc (13 * sizeof (T));
|
void* a = new (p) T[13];
|
void* a = new (p) T[13];
|
if (p != a)
|
if (p != a)
|
exit (i);
|
exit (i);
|
}
|
}
|
|
|
template
|
template
|
void check_cookie (int i)
|
void check_cookie (int i)
|
{
|
{
|
void* a = new T[11];
|
void* a = new T[11];
|
size_t x;
|
size_t x;
|
|
|
// Compute the cookie location manually.
|
// Compute the cookie location manually.
|
#ifdef __ARM_EABI__
|
#ifdef __ARM_EABI__
|
x = 8;
|
x = 8;
|
#else
|
#else
|
x = __alignof__ (T);
|
x = __alignof__ (T);
|
if (x < sizeof (size_t))
|
if (x < sizeof (size_t))
|
x = sizeof (size_t);
|
x = sizeof (size_t);
|
#endif
|
#endif
|
if ((char *) a - x != (char *) p)
|
if ((char *) a - x != (char *) p)
|
exit (i);
|
exit (i);
|
|
|
// Check the cookie value.
|
// Check the cookie value.
|
size_t *sp = ((size_t *) a) - 1;
|
size_t *sp = ((size_t *) a) - 1;
|
if (*sp != 11)
|
if (*sp != 11)
|
exit (i);
|
exit (i);
|
|
|
#ifdef __ARM_EABI__
|
#ifdef __ARM_EABI__
|
sp = ((size_t *) a) - 2;
|
sp = ((size_t *) a) - 2;
|
if (*sp != sizeof (T))
|
if (*sp != sizeof (T))
|
exit (i);
|
exit (i);
|
#endif
|
#endif
|
}
|
}
|
|
|
template
|
template
|
void check_placement_cookie (int i)
|
void check_placement_cookie (int i)
|
{
|
{
|
p = malloc (sizeof (T) * 11 + 100);
|
p = malloc (sizeof (T) * 11 + 100);
|
void* a = new (p) T[11];
|
void* a = new (p) T[11];
|
size_t x;
|
size_t x;
|
|
|
// Compute the cookie location manually.
|
// Compute the cookie location manually.
|
#ifdef __ARM_EABI__
|
#ifdef __ARM_EABI__
|
x = 8;
|
x = 8;
|
#else
|
#else
|
x = __alignof__ (T);
|
x = __alignof__ (T);
|
if (x < sizeof (size_t))
|
if (x < sizeof (size_t))
|
x = sizeof (size_t);
|
x = sizeof (size_t);
|
#endif
|
#endif
|
if ((char *) a - x != (char *) p)
|
if ((char *) a - x != (char *) p)
|
exit (i);
|
exit (i);
|
|
|
// Check the cookie value.
|
// Check the cookie value.
|
size_t *sp = ((size_t *) a) - 1;
|
size_t *sp = ((size_t *) a) - 1;
|
if (*sp != 11)
|
if (*sp != 11)
|
exit (i);
|
exit (i);
|
|
|
#ifdef __ARM_EABI__
|
#ifdef __ARM_EABI__
|
sp = ((size_t *) a) - 2;
|
sp = ((size_t *) a) - 2;
|
if (*sp != sizeof (T))
|
if (*sp != sizeof (T))
|
exit (i);
|
exit (i);
|
#endif
|
#endif
|
}
|
}
|
|
|
struct X {};
|
struct X {};
|
|
|
template
|
template
|
struct Y { int i; virtual void f () {} };
|
struct Y { int i; virtual void f () {} };
|
|
|
// A class with a non-trivial destructor -- it needs a cookie.
|
// A class with a non-trivial destructor -- it needs a cookie.
|
struct Z { ~Z () {} };
|
struct Z { ~Z () {} };
|
// Likewise, but this class needs a bigger cookie so that the array
|
// Likewise, but this class needs a bigger cookie so that the array
|
// elements are correctly aligned.
|
// elements are correctly aligned.
|
struct Z2 { ~Z2 () {} long double d; };
|
struct Z2 { ~Z2 () {} long double d; };
|
|
|
struct W1 { void operator delete[] (void *, size_t) {} };
|
struct W1 { void operator delete[] (void *, size_t) {} };
|
struct W2 { void operator delete[] (void *) {}
|
struct W2 { void operator delete[] (void *) {}
|
void operator delete[] (void *, size_t) {} };
|
void operator delete[] (void *, size_t) {} };
|
struct W3 { void operator delete[] (void *, size_t) {}
|
struct W3 { void operator delete[] (void *, size_t) {}
|
void operator delete[] (void *) {} };
|
void operator delete[] (void *) {} };
|
struct W4 : public W1 {};
|
struct W4 : public W1 {};
|
|
|
struct V { void *operator new[] (size_t s, void *p)
|
struct V { void *operator new[] (size_t s, void *p)
|
{ return p; }
|
{ return p; }
|
~V () {}
|
~V () {}
|
};
|
};
|
|
|
int main ()
|
int main ()
|
{
|
{
|
// There should be no cookies for types with trivial destructors.
|
// There should be no cookies for types with trivial destructors.
|
check_no_cookie (1);
|
check_no_cookie (1);
|
check_no_cookie (2);
|
check_no_cookie (2);
|
check_no_cookie > (3);
|
check_no_cookie > (3);
|
|
|
// There should be no cookies for allocations using global placement
|
// There should be no cookies for allocations using global placement
|
// new.
|
// new.
|
check_no_placement_cookie (4);
|
check_no_placement_cookie (4);
|
check_no_placement_cookie (5);
|
check_no_placement_cookie (5);
|
check_no_placement_cookie (6);
|
check_no_placement_cookie (6);
|
|
|
// There should be a cookie when using a non-trivial destructor.
|
// There should be a cookie when using a non-trivial destructor.
|
check_cookie (7);
|
check_cookie (7);
|
check_cookie (8);
|
check_cookie (8);
|
|
|
// There should be a cookie when using the two-argument array delete
|
// There should be a cookie when using the two-argument array delete
|
// operator.
|
// operator.
|
check_cookie (9);
|
check_cookie (9);
|
check_cookie (10);
|
check_cookie (10);
|
// But not when the one-argument version is also available.
|
// But not when the one-argument version is also available.
|
check_no_cookie (11);
|
check_no_cookie (11);
|
check_no_cookie (12);
|
check_no_cookie (12);
|
|
|
// There should be a cookie when using a non-global placement new.
|
// There should be a cookie when using a non-global placement new.
|
check_placement_cookie (13);
|
check_placement_cookie (13);
|
}
|
}
|
|
|
#else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
|
#else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
|
|
|
int main ()
|
int main ()
|
{
|
{
|
}
|
}
|
|
|
#endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
|
#endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
|
|
|