4 * This program checks if the compiler / platform supports exceptions,
5 * in particular, if raising exceptions in constructors work. The
6 * motivation for this test was a discussion on the development
7 * mailing list, and the documentation was captured in:
9 * http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=3715
12 #include "test_config.h"
14 // The first part of the test is to compile this line. If the program
15 // does not compile the platform is just too broken.
18 // ... using exceptions with C++ also implies using the standard
22 // For extra challenge, we use the anonymous namespace
29 bool had_failure
= false;
31 void check_constructor_count(int expected
,
32 char const * filename
,
34 void check_destructor_count(int expected
,
35 char const * filename
,
37 void check_alloc_count(int expected
,
38 char const * filename
,
41 void never_reached(char const * filename
,
64 void * operator new(size_t n
)
67 return ::operator new(n
);
69 void operator delete(void * x
)
72 return ::operator delete(x
);
79 * Create a class that can raise exceptions in its constructor
82 class May_Pop
: public Base
85 explicit May_Pop(bool do_raise
)
86 // Even if an exception is raised, the base object is fully
87 // constructed and must be fully destructed ...
92 throw std::runtime_error("requested exception");
94 // ... if an exception is raised this object is never
95 // initialized and no constructor / destructor calls should take
104 class Aggregate
: public Base
113 * Constructor. Element m1 is fully initialized, its constructors
114 * and destructors should run, m2 is partially initialized, its
115 * destructor never runs, m3 is never initialized, neither its
116 * constructor nor destructor runs.
130 run_main (int, ACE_TCHAR
*[])
132 ACE_START_TEST (ACE_TEXT("Compiler_Features_10_Test"));
135 // ... start the test fresh ...
137 // Let's try to build a simple object and destroy it, without any
138 // exceptions raised ...
140 // ... two instances of the base class should be created ...
141 check_constructor_count(2, __FILE__
, __LINE__
);
142 // ... but only one instance is destroyed at this point ...
143 check_destructor_count(1, __FILE__
, __LINE__
);
147 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("Error: Unexpected exception caught\n")));
149 // ... now both instances are gone ...
150 check_destructor_count(2, __FILE__
, __LINE__
);
154 // ... start the test fresh ...
156 // ... now raise an exception ...
158 never_reached(__FILE__
, __LINE__
);
162 // ... only one instance gets created ...
163 check_constructor_count(1, __FILE__
, __LINE__
);
164 // ... and it is gone ...
165 check_destructor_count(1, __FILE__
, __LINE__
);
170 // ... start the test fresh ...
172 // ... now build a complex object with a failure in the middle ...
174 never_reached(__FILE__
, __LINE__
);
178 // ... check the expectations ...
179 check_constructor_count(4, __FILE__
, __LINE__
);
180 check_destructor_count(4, __FILE__
, __LINE__
);
185 // ... start the test fresh ...
187 std::auto_ptr
<Aggregate
> b(new Aggregate
);
188 never_reached(__FILE__
, __LINE__
);
192 // ... check the expectations ...
193 check_constructor_count(4, __FILE__
, __LINE__
);
194 check_destructor_count(4, __FILE__
, __LINE__
);
195 check_alloc_count(1, __FILE__
, __LINE__
);
206 check_constructor_count(int expected
,
207 char const * filename
,
210 if (constructors
== expected
)
215 ACE_ERROR ((LM_ERROR
,
216 ACE_TEXT("Expected %d constructor calls, had %d -- (%s:%d)\n"),
217 expected
, constructors
, filename
, lineno
));
221 check_destructor_count(int expected
,
222 char const * filename
,
225 if (destructors
== expected
)
230 ACE_ERROR ((LM_ERROR
,
231 ACE_TEXT("Expected %d destructor calls, had %d -- (%s:%d)\n"),
232 expected
, destructors
, filename
, lineno
));
236 check_alloc_count(int expected
,
237 char const * filename
,
240 if (allocs
== expected
&& deallocs
== expected
)
245 if (allocs
!= expected
)
247 ACE_ERROR ((LM_ERROR
,
248 ACE_TEXT("Expected %d alloc calls, had %d -- (%s:%d)\n"),
249 expected
, allocs
, filename
, lineno
));
251 if (deallocs
!= expected
)
253 ACE_ERROR ((LM_ERROR
,
254 ACE_TEXT("Expected %d dealloc calls, had %d -- (%s:%d)\n"),
255 expected
, deallocs
, filename
, lineno
));
260 never_reached(char const * filename
,
264 ACE_ERROR ((LM_ERROR
,
265 ACE_TEXT("Code should not have reached (%s:%d)\n"),