Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / libc++abi / trunk / test / test_vector1.cpp
1 //===---------------------------- test_vector.cpp -------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "cxxabi.h"
11
12 #include <iostream>
13 #include <cstdlib>
14
15 //  Wrapper routines
16 void *my_alloc2 ( size_t sz ) {
17     void *p = std::malloc ( sz );
18 //  std::printf ( "Allocated %ld bytes at %lx\n", sz, (unsigned long) p );  
19     return p;
20     }
21     
22 void my_dealloc2 ( void *p ) {
23 //  std::printf ( "Freeing %lx\n", (unsigned long) p ); 
24     std::free ( p ); 
25     }
26
27 void my_dealloc3 ( void *p, size_t   sz   ) {
28 //  std::printf ( "Freeing %lx (size %ld)\n", (unsigned long) p, sz );  
29     std::free ( p ); 
30     }
31
32 void my_construct ( void *p ) {
33 //  std::printf ( "Constructing %lx\n", (unsigned long) p );
34     }
35
36 void my_destruct  ( void *p ) {
37 //  std::printf ( "Destructing  %lx\n", (unsigned long) p );
38     }
39
40 int gCounter;
41 void count_construct ( void *p ) { ++gCounter; }
42 void count_destruct  ( void *p ) { --gCounter; }
43
44
45 int gConstructorCounter;
46 int gConstructorThrowTarget;
47 int gDestructorCounter;
48 int gDestructorThrowTarget;
49 void throw_construct ( void *p ) { if ( gConstructorCounter   == gConstructorThrowTarget ) throw 1; ++gConstructorCounter; }
50 void throw_destruct  ( void *p ) { if ( ++gDestructorCounter  == gDestructorThrowTarget  ) throw 2; }
51
52 #if __cplusplus >= 201103L
53 #   define CAN_THROW noexcept(false)
54 #else
55 #   define CAN_THROW
56 #endif
57
58 struct vec_on_stack {
59     void *storage;
60     vec_on_stack () : storage ( __cxxabiv1::__cxa_vec_new    (            10, 40, 8, throw_construct, throw_destruct )) {}
61     ~vec_on_stack () CAN_THROW {__cxxabiv1::__cxa_vec_delete ( storage,       40, 8,                  throw_destruct );  }
62     };
63
64 //  Test calls with empty constructors and destructors
65 int test_empty ( ) {
66     void *one, *two, *three;
67
68 //  Try with no padding and no con/destructors
69     one     = __cxxabiv1::__cxa_vec_new ( 10, 40, 0, NULL, NULL );
70     two     = __cxxabiv1::__cxa_vec_new2( 10, 40, 0, NULL, NULL, my_alloc2, my_dealloc2 );
71     three   = __cxxabiv1::__cxa_vec_new3( 10, 40, 0, NULL, NULL, my_alloc2, my_dealloc3 );
72
73     __cxxabiv1::__cxa_vec_delete ( one,       40, 0, NULL );
74     __cxxabiv1::__cxa_vec_delete2( two,       40, 0, NULL, my_dealloc2 );
75     __cxxabiv1::__cxa_vec_delete3( three,     40, 0, NULL, my_dealloc3 );
76     
77 //  Try with no padding
78     one     = __cxxabiv1::__cxa_vec_new ( 10, 40, 0, my_construct, my_destruct );
79     two     = __cxxabiv1::__cxa_vec_new2( 10, 40, 0, my_construct, my_destruct, my_alloc2, my_dealloc2 );
80     three   = __cxxabiv1::__cxa_vec_new3( 10, 40, 0, my_construct, my_destruct, my_alloc2, my_dealloc3 );
81
82     __cxxabiv1::__cxa_vec_delete ( one,       40, 0, my_destruct );
83     __cxxabiv1::__cxa_vec_delete2( two,       40, 0, my_destruct, my_dealloc2 );
84     __cxxabiv1::__cxa_vec_delete3( three,     40, 0, my_destruct, my_dealloc3 );
85
86 //  Padding and no con/destructors 
87     one     = __cxxabiv1::__cxa_vec_new ( 10, 40, 8, NULL, NULL );
88     two     = __cxxabiv1::__cxa_vec_new2( 10, 40, 8, NULL, NULL, my_alloc2, my_dealloc2 );
89     three   = __cxxabiv1::__cxa_vec_new3( 10, 40, 8, NULL, NULL, my_alloc2, my_dealloc3 );
90
91     __cxxabiv1::__cxa_vec_delete ( one,       40, 8, NULL );
92     __cxxabiv1::__cxa_vec_delete2( two,       40, 8, NULL, my_dealloc2 );
93     __cxxabiv1::__cxa_vec_delete3( three,     40, 8, NULL, my_dealloc3 );
94
95 //  Padding with con/destructors 
96     one     = __cxxabiv1::__cxa_vec_new ( 10, 40, 8, my_construct, my_destruct );
97     two     = __cxxabiv1::__cxa_vec_new2( 10, 40, 8, my_construct, my_destruct, my_alloc2, my_dealloc2 );
98     three   = __cxxabiv1::__cxa_vec_new3( 10, 40, 8, my_construct, my_destruct, my_alloc2, my_dealloc3 );
99
100     __cxxabiv1::__cxa_vec_delete ( one,       40, 8, my_destruct );
101     __cxxabiv1::__cxa_vec_delete2( two,       40, 8, my_destruct, my_dealloc2 );
102     __cxxabiv1::__cxa_vec_delete3( three,     40, 8, my_destruct, my_dealloc3 );
103
104     return 0;
105     }
106
107 //  Make sure the constructors and destructors are matched
108 int test_counted ( ) {
109     int retVal = 0;
110     void *one, *two, *three;
111
112 //  Try with no padding
113     gCounter = 0;   
114     one     = __cxxabiv1::__cxa_vec_new ( 10, 40, 0, count_construct, count_destruct );
115     two     = __cxxabiv1::__cxa_vec_new2( 10, 40, 0, count_construct, count_destruct, my_alloc2, my_dealloc2 );
116     three   = __cxxabiv1::__cxa_vec_new3( 10, 40, 0, count_construct, count_destruct, my_alloc2, my_dealloc3 );
117     
118     __cxxabiv1::__cxa_vec_delete ( one,       40, 0, count_destruct );
119     __cxxabiv1::__cxa_vec_delete2( two,       40, 0, count_destruct, my_dealloc2 );
120     __cxxabiv1::__cxa_vec_delete3( three,     40, 0, count_destruct, my_dealloc3 );
121     
122 //  Since there was no padding, the # of elements in the array are not stored 
123 //  and the destructors are not called.
124     if ( gCounter != 30 ) {
125         std::cerr << "Mismatched Constructor/Destructor calls (1)" << std::endl;
126         std::cerr << "  Expected 30, got " << gCounter << std::endl;
127         retVal = 1;
128         }
129     
130     gCounter = 0;   
131     one     = __cxxabiv1::__cxa_vec_new ( 10, 40, 8, count_construct, count_destruct );
132     two     = __cxxabiv1::__cxa_vec_new2( 10, 40, 8, count_construct, count_destruct, my_alloc2, my_dealloc2 );
133     three   = __cxxabiv1::__cxa_vec_new3( 10, 40, 8, count_construct, count_destruct, my_alloc2, my_dealloc3 );
134
135     __cxxabiv1::__cxa_vec_delete ( one,       40, 8, count_destruct );
136     __cxxabiv1::__cxa_vec_delete2( two,       40, 8, count_destruct, my_dealloc2 );
137     __cxxabiv1::__cxa_vec_delete3( three,     40, 8, count_destruct, my_dealloc3 );
138
139     if ( gCounter != 0 ) {
140         std::cerr << "Mismatched Constructor/Destructor calls (2)" << std::endl;
141         std::cerr << "  Expected 0, got " << gCounter << std::endl;
142         retVal = 1;
143         }
144
145     return retVal;
146     }
147     
148 //  Make sure the constructors and destructors are matched
149 int test_exception_in_constructor ( ) {
150     int retVal = 0;
151     void *one, *two, *three;
152
153 //  Try with no padding
154     gConstructorCounter = gDestructorCounter = 0;
155     gConstructorThrowTarget = 15;
156     gDestructorThrowTarget  = -1;
157     try {
158         one = two = three = NULL;
159         one     = __cxxabiv1::__cxa_vec_new ( 10, 40, 0, throw_construct, throw_destruct );
160         two     = __cxxabiv1::__cxa_vec_new2( 10, 40, 0, throw_construct, throw_destruct, my_alloc2, my_dealloc2 );
161         three   = __cxxabiv1::__cxa_vec_new3( 10, 40, 0, throw_construct, throw_destruct, my_alloc2, my_dealloc3 );
162         }
163     catch ( int i ) {}
164     
165     __cxxabiv1::__cxa_vec_delete ( one,       40, 0, throw_destruct );
166     __cxxabiv1::__cxa_vec_delete2( two,       40, 0, throw_destruct, my_dealloc2 );
167     __cxxabiv1::__cxa_vec_delete3( three,     40, 0, throw_destruct, my_dealloc3 );
168     
169 //  Since there was no padding, the # of elements in the array are not stored 
170 //  and the destructors are not called.
171 //  Since we threw after 15 calls to the constructor, we should see 5 calls to
172 //      the destructor from the partially constructed array.
173     if ( gConstructorCounter - gDestructorCounter != 10 ) {
174         std::cerr << "Mismatched Constructor/Destructor calls (1C)" << std::endl;
175         std::cerr << gConstructorCounter << " constructors, but " << 
176                 gDestructorCounter << " destructors" << std::endl;
177         retVal = 1;
178         }
179     
180     gConstructorCounter = gDestructorCounter = 0;
181     gConstructorThrowTarget = 15;
182     gDestructorThrowTarget  = -1;
183     try {
184         one = two = three = NULL;
185         one     = __cxxabiv1::__cxa_vec_new ( 10, 40, 8, throw_construct, throw_destruct );
186         two     = __cxxabiv1::__cxa_vec_new2( 10, 40, 8, throw_construct, throw_destruct, my_alloc2, my_dealloc2 );
187         three   = __cxxabiv1::__cxa_vec_new3( 10, 40, 8, throw_construct, throw_destruct, my_alloc2, my_dealloc3 );
188         }
189     catch ( int i ) {}
190     
191     __cxxabiv1::__cxa_vec_delete ( one,       40, 8, throw_destruct );
192     __cxxabiv1::__cxa_vec_delete2( two,       40, 8, throw_destruct, my_dealloc2 );
193     __cxxabiv1::__cxa_vec_delete3( three,     40, 8, throw_destruct, my_dealloc3 );
194
195     if ( gConstructorCounter != gDestructorCounter ) {
196         std::cerr << "Mismatched Constructor/Destructor calls (2C)" << std::endl;
197         std::cerr << gConstructorCounter << " constructors, but " << 
198                 gDestructorCounter << " destructors" << std::endl;
199         retVal = 1;
200         }
201
202     return retVal;
203     }
204
205 //  Make sure the constructors and destructors are matched
206 int test_exception_in_destructor ( ) {
207     int retVal = 0;
208     void *one, *two, *three;
209
210 //  Throw from within a destructor
211     gConstructorCounter = gDestructorCounter = 0;
212     gConstructorThrowTarget = -1;
213     gDestructorThrowTarget  = 15;
214     try {
215         one = two = three = NULL;
216         one     = __cxxabiv1::__cxa_vec_new ( 10, 40, 8, throw_construct, throw_destruct );
217         two     = __cxxabiv1::__cxa_vec_new2( 10, 40, 8, throw_construct, throw_destruct, my_alloc2, my_dealloc2 );
218         three   = __cxxabiv1::__cxa_vec_new3( 10, 40, 8, throw_construct, throw_destruct, my_alloc2, my_dealloc3 );
219         }
220     catch ( int i ) {}
221     
222     try {
223         __cxxabiv1::__cxa_vec_delete ( one,       40, 8, throw_destruct );
224         __cxxabiv1::__cxa_vec_delete2( two,       40, 8, throw_destruct, my_dealloc2 );
225         __cxxabiv1::__cxa_vec_delete3( three,     40, 8, throw_destruct, my_dealloc3 );
226         }
227     catch ( int i ) {}
228     
229 //  We should have thrown in the middle of cleaning up "two", which means that
230 //  there should be 20 calls to the destructor, and "three" was not cleaned up.
231     if ( gConstructorCounter != 30 || gDestructorCounter != 20 ) {
232         std::cerr << "Unexpected Constructor/Destructor calls (1D)" << std::endl;
233         std::cerr << "Expected (30, 20), but got (" << gConstructorCounter << ", " << 
234                 gDestructorCounter << ")" << std::endl;
235         retVal = 1;
236         }
237
238 //  Try throwing from a destructor - should be fine.
239     gConstructorCounter = gDestructorCounter = 0;
240     gConstructorThrowTarget = -1;
241     gDestructorThrowTarget  = 5;
242     try { vec_on_stack v; }
243     catch ( int i ) {}
244     
245     if ( gConstructorCounter != gDestructorCounter ) {
246         std::cerr << "Mismatched Constructor/Destructor calls (2D)" << std::endl;
247         std::cerr << gConstructorCounter << " constructors, but " << 
248                 gDestructorCounter << " destructors" << std::endl;
249         retVal = 1;
250         }
251
252     return retVal;
253     }
254
255 int main ( int argc, char *argv [] ) {
256     int retVal = 0;
257     retVal += test_empty ();
258     retVal += test_counted ();
259     retVal += test_exception_in_constructor ();
260     retVal += test_exception_in_destructor ();
261     return retVal;
262     }