OSDN Git Service

273d137b85e64004cc8a05084b5274eb678c60d1
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / g++.old-deja / g++.abi / arraynew.C
1 // { dg-do run  }
2 // Origin: Mark Mitchell <mark@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 #ifdef __ARM_EABI__
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 #ifdef __ARM_EABI__
58   size_t *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 #ifdef __ARM_EABI__
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 #ifdef __ARM_EABI__
88   size_t *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) */