1 // { dg-do run }
2 // Test __cxa_vec routines
3 // Copyright (C) 2000 Free Software Foundation, Inc.
4 // Contributed by Nathan Sidwell 7 Apr 2000 <nathan@nathan@codesourcery.com>
5
6 #if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
7 #include <cxxabi.h>
8 #include <stdio.h>
9 #include <new>
10 #include <stdlib.h>
11 #include <setjmp.h>
12
13 static int ctor_count = 0;
14 static int dtor_count = 0;
15 static bool dtor_repeat = false;
16
17 // our pseudo ctors and dtors
ctor(void *)18 static void ctor (void *)
19 {
20 if (!ctor_count)
21 throw 1;
22 ctor_count--;
23 }
24
dtor(void *)25 static void dtor (void *)
26 {
27 if (!dtor_count)
28 {
29 if (!dtor_repeat)
30 dtor_count--;
31 throw 1;
32 }
33 dtor_count--;
34 }
35
36 // track new and delete
37 static int blocks = 0;
throw(std::bad_alloc)38 void *operator new[] (std::size_t size) throw (std::bad_alloc)
39 {
40 void *ptr = malloc (size);
41
42 if (!ptr)
43 throw std::bad_alloc ();
44 blocks++;
45 return ptr;
46 }
47
throw()48 void operator delete[] (void *ptr) throw ()
49 {
50 if (ptr)
51 {
52 free (ptr);
53 blocks--;
54 }
55 }
56 static jmp_buf jump;
57
58 // allocate and delete an array with no problems
test0()59 void test0 ()
60 {
61 static bool started = false;
62
63 if (!started)
64 {
65 started = true;
66 std::set_terminate (test0);
67
68 ctor_count = dtor_count = 5;
69 dtor_repeat = false;
70 blocks = 0;
71
72 try
73 {
74 void *ary = abi::__cxa_vec_new (5, 1, sizeof (std::size_t), ctor, dtor);
75 abi::__cxa_vec_delete (ary, 1, sizeof (std::size_t), dtor);
76 if (ctor_count || dtor_count || blocks)
77 longjmp (jump, 1);
78 }
79 catch (...)
80 {
81 longjmp (jump, 2);
82 }
83 }
84 else
85 {
86 longjmp (jump, 3);
87 }
88 return;
89 }
90
91 // allocate and delete an array with exception on ctor
test1()92 void test1 ()
93 {
94 static bool started = false;
95
96 if (!started)
97 {
98 started = true;
99 std::set_terminate (test1);
100
101 ctor_count = dtor_count = 5;
102 dtor_repeat = false;
103 blocks = 0;
104
105 ctor_count = 4;
106 try
107 {
108 void *ary = abi::__cxa_vec_new (5, 1, sizeof (std::size_t), ctor, dtor);
109 longjmp (jump, 1);
110 }
111 catch (...)
112 {
113 // we expect to get here
114 if (ctor_count || dtor_count != 1 || blocks)
115 longjmp (jump, 2);
116 }
117 }
118 else
119 {
120 longjmp (jump, 3);
121 }
122 return;
123 }
124
125 // allocate and delete an array with exception on dtor
test2()126 void test2 ()
127 {
128 static bool started = false;
129
130 if (!started)
131 {
132 started = true;
133 std::set_terminate (test2);
134 ctor_count = dtor_count = 5;
135 dtor_repeat = false;
136 blocks = 0;
137
138 dtor_count = 3;
139 try
140 {
141 void *ary = abi::__cxa_vec_new (5, 1, sizeof (std::size_t), ctor, dtor);
142 abi::__cxa_vec_delete (ary, 1, sizeof (std::size_t), dtor);
143 longjmp (jump, 1);
144 }
145 catch (...)
146 {
147 // we expect to get here
148 if (ctor_count || dtor_count != -2u || blocks)
149 longjmp (jump, 2);
150 }
151 }
152 else
153 {
154 longjmp (jump, 3);
155 }
156 return;
157 }
158
159 // allocate an array with double exception on dtor
test3()160 void test3 ()
161 {
162 static bool started = false;
163
164 if (!started)
165 {
166 started = true;
167 std::set_terminate (test3);
168
169 ctor_count = dtor_count = 5;
170 dtor_repeat = false;
171 blocks = 0;
172
173 dtor_count = 3;
174 dtor_repeat = true;
175 try
176 {
177 void *ary = abi::__cxa_vec_new (5, 1, sizeof (std::size_t), ctor, dtor);
178 abi::__cxa_vec_delete (ary, 1, sizeof (std::size_t), dtor);
179 longjmp (jump, 1);
180 }
181 catch (...)
182 {
183 // we do not expect to get here
184 longjmp (jump, 2);
185 }
186 }
187 else
188 {
189 // we expect to get here (via terminate)
190 if (ctor_count || dtor_count || blocks != 1)
191 longjmp (jump, 3);
192 longjmp (jump, -1);
193 }
194 return;
195 }
196
197 // allocate an array with exception on ctor and exception in cleanup
test4()198 void test4 ()
199 {
200 static bool started = false;
201
202 if (!started)
203 {
204 started = true;
205 std::set_terminate (test4);
206
207 ctor_count = dtor_count = 5;
208 dtor_repeat = false;
209 blocks = 0;
210
211 ctor_count = 3;
212 dtor_count = 2;
213 try
214 {
215 void *ary = abi::__cxa_vec_new (5, 1, sizeof (std::size_t), ctor, dtor);
216 longjmp (jump, 1);
217 }
218 catch (...)
219 {
220 // we do not expect to get here
221 longjmp (jump, 2);
222 }
223 }
224 else
225 {
226 // we expect to get here (via terminate)
227 if (ctor_count || dtor_count != -1u || blocks != 1)
228 longjmp (jump, 3);
229 longjmp (jump, -1);
230 }
231 return;
232 }
233
234 static void (*tests[])() =
235 {
236 test0,
237 test1,
238 test2,
239 test3,
240 test4,
241 NULL
242 };
243
main()244 int main ()
245 {
246 int ix;
247 int n;
248 int errors = 0;
249
250 for (ix = 0; tests[ix]; ix++)
251 {
252 if (n = setjmp (jump))
253 {
254 if (n > 0)
255 {
256 printf ("test %d failed %d\n", ix, n);
257 errors++;
258 }
259 }
260 else
261 tests[ix] ();
262 }
263 return errors;
264 }
265
266 #else
main()267 int main ()
268 {
269 return 0;
270 }
271 #endif
272