2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / gcc / testsuite / g++.old-deja / g++.abi / arraynew.C
blob3b11796c2719adea6013132be13bc2d4b313bd35
1 // { dg-do run  }
2 // Origin: Mark Mitchell <mark@codesourcery.com>
4 #if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
6 #include <cstdlib>
7 #include <new>
9 void* p;
11 void* operator new[](size_t s) throw (std::bad_alloc)
13   // Record the base of the last array allocated.
14   p = malloc (s);
15   return p;
18 template <typename T>
19 void check_no_cookie (int i)
21   void* a = new T[7];
22   if (p != a)
23     exit (i);
26 template <typename T>
27 void check_no_placement_cookie (int i)
29   p = malloc (13 * sizeof (T));
30   void* a = new (p) T[13];
31   if (p != a)
32     exit (i);
35 template <typename T>
36 void check_cookie (int i)
38   void* a = new T[11];
39   
40   // Compute the cookie location manually.
41   size_t x = __alignof__ (T);
42   if (x < sizeof (size_t))
43     x = sizeof (size_t);
44   if ((char *) a - x != (char *) p)
45     exit (i);
47   // Check the cookie value.
48   size_t *sp = ((size_t *) a) - 1;
49   if (*sp != 11)
50     exit (i);
53 template <typename T>
54 void check_placement_cookie (int i)
56   p = malloc (sizeof (T) * 11 + 100);
57   void* a = new (p) T[11];
58   
59   // Compute the cookie location manually.
60   size_t x = __alignof__ (T);
61   if (x < sizeof (size_t))
62     x = sizeof (size_t);
63   if ((char *) a - x != (char *) p)
64     exit (i);
66   // Check the cookie value.
67   size_t *sp = ((size_t *) a) - 1;
68   if (*sp != 11)
69     exit (i);
72 struct X {};
74 template <typename T>
75 struct Y { int i; virtual void f () {}; };
77 // A class with a non-trivial destructor -- it needs a cookie.
78 struct Z { ~Z () {}; };
79 // Likewise, but this class needs a bigger cookie so that the array
80 // elements are correctly aligned.
81 struct Z2 { ~Z2 () {}; long double d; };
82   
83 struct W1 { void operator delete[] (void *, size_t) {}; };
84 struct W2 { void operator delete[] (void *) {}; 
85             void operator delete[] (void *, size_t) {}; };
86 struct W3 { void operator delete[] (void *, size_t) {}; 
87             void operator delete[] (void *) {}; };
88 struct W4 : public W1 {};
90 struct V { void *operator new[] (size_t s, void *p) 
91              { return p; }
92            ~V () {}
93          };
94    
95 int main ()
97   // There should be no cookies for types with trivial destructors.
98   check_no_cookie<int> (1);
99   check_no_cookie<X> (2);
100   check_no_cookie<Y<double> > (3);
102   // There should be no cookies for allocations using global placement
103   // new.
104   check_no_placement_cookie<int> (4);
105   check_no_placement_cookie<X> (5);
106   check_no_placement_cookie<Z> (6);
108   // There should be a cookie when using a non-trivial destructor.
109   check_cookie<Z> (7);
110   check_cookie<Z2> (8);
111   
112   // There should be a cookie when using the two-argument array delete
113   // operator.
114   check_cookie<W1> (9);
115   check_cookie<W4> (10);
116   // But not when the one-argument version is also available.
117   check_no_cookie<W2> (11);
118   check_no_cookie<W3> (12);
120   // There should be a cookie when using a non-global placement new.
121   check_placement_cookie<V> (13);
124 #else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
126 int main () 
130 #endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */