1 // { dg-do run } 2 // Origin: Mark Mitchell <mark (at) codesourcery.com> 3 4 #if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 5 6 #include <cstdlib> 7 #include <new> 8 9 void* p; 10 11 void* operator new[](size_t s) throw (std::bad_alloc) 12 { 13 // Record the base of the last array allocated. 14 p = malloc (s); 15 return p; 16 } 17 18 template <typename T> 19 void check_no_cookie (int i) 20 { 21 void* a = new T[7]; 22 if (p != a) 23 exit (i); 24 } 25 26 template <typename T> 27 void check_no_placement_cookie (int i) 28 { 29 p = malloc (13 * sizeof (T)); 30 void* a = new (p) T[13]; 31 if (p != a) 32 exit (i); 33 } 34 35 template <typename T> 36 void check_cookie (int i) 37 { 38 void* a = new T[11]; 39 size_t x; 40 41 // Compute the cookie location manually. 42 #if defined(__ARM_EABI__) || defined(__le32__) 43 x = 8; 44 #else 45 x = __alignof__ (T); 46 if (x < sizeof (size_t)) 47 x = sizeof (size_t); 48 #endif 49 if ((char *) a - x != (char *) p) 50 exit (i); 51 52 // Check the cookie value. 53 size_t *sp = ((size_t *) a) - 1; 54 if (*sp != 11) 55 exit (i); 56 57 #if defined(__ARM_EABI__) || defined(__le32__) 58 sp = ((size_t *) a) - 2; 59 if (*sp != sizeof (T)) 60 exit (i); 61 #endif 62 } 63 64 template <typename T> 65 void check_placement_cookie (int i) 66 { 67 p = malloc (sizeof (T) * 11 + 100); 68 void* a = new (p) T[11]; 69 size_t x; 70 71 // Compute the cookie location manually. 72 #if defined(__ARM_EABI__) || defined(__le32__) 73 x = 8; 74 #else 75 x = __alignof__ (T); 76 if (x < sizeof (size_t)) 77 x = sizeof (size_t); 78 #endif 79 if ((char *) a - x != (char *) p) 80 exit (i); 81 82 // Check the cookie value. 83 size_t *sp = ((size_t *) a) - 1; 84 if (*sp != 11) 85 exit (i); 86 87 #if defined(__ARM_EABI__) || defined(__le32__) 88 sp = ((size_t *) a) - 2; 89 if (*sp != sizeof (T)) 90 exit (i); 91 #endif 92 } 93 94 struct X {}; 95 96 template <typename T> 97 struct Y { int i; virtual void f () {} }; 98 99 // A class with a non-trivial destructor -- it needs a cookie. 100 struct Z { ~Z () {} }; 101 // Likewise, but this class needs a bigger cookie so that the array 102 // elements are correctly aligned. 103 struct Z2 { ~Z2 () {} long double d; }; 104 105 struct W1 { void operator delete[] (void *, size_t) {} }; 106 struct W2 { void operator delete[] (void *) {} 107 void operator delete[] (void *, size_t) {} }; 108 struct W3 { void operator delete[] (void *, size_t) {} 109 void operator delete[] (void *) {} }; 110 struct W4 : public W1 {}; 111 112 struct V { void *operator new[] (size_t s, void *p) 113 { return p; } 114 ~V () {} 115 }; 116 117 int main () 118 { 119 // There should be no cookies for types with trivial destructors. 120 check_no_cookie<int> (1); 121 check_no_cookie<X> (2); 122 check_no_cookie<Y<double> > (3); 123 124 // There should be no cookies for allocations using global placement 125 // new. 126 check_no_placement_cookie<int> (4); 127 check_no_placement_cookie<X> (5); 128 check_no_placement_cookie<Z> (6); 129 130 // There should be a cookie when using a non-trivial destructor. 131 check_cookie<Z> (7); 132 check_cookie<Z2> (8); 133 134 // There should be a cookie when using the two-argument array delete 135 // operator. 136 check_cookie<W1> (9); 137 check_cookie<W4> (10); 138 // But not when the one-argument version is also available. 139 check_no_cookie<W2> (11); 140 check_no_cookie<W3> (12); 141 142 // There should be a cookie when using a non-global placement new. 143 check_placement_cookie<V> (13); 144 } 145 146 #else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */ 147 148 int main () 149 { 150 } 151 152 #endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */ 153