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.
129 run_main (int, ACE_TCHAR
*[])
131 ACE_START_TEST (ACE_TEXT("Compiler_Features_10_Test"));
134 // ... start the test fresh ...
136 // Let's try to build a simple object and destroy it, without any
137 // exceptions raised ...
139 // ... two instances of the base class should be created ...
140 check_constructor_count(2, __FILE__
, __LINE__
);
141 // ... but only one instance is destroyed at this point ...
142 check_destructor_count(1, __FILE__
, __LINE__
);
146 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("Error: Unexpected exception caught\n")));
148 // ... now both instances are gone ...
149 check_destructor_count(2, __FILE__
, __LINE__
);
153 // ... start the test fresh ...
155 // ... now raise an exception ...
157 never_reached(__FILE__
, __LINE__
);
161 // ... only one instance gets created ...
162 check_constructor_count(1, __FILE__
, __LINE__
);
163 // ... and it is gone ...
164 check_destructor_count(1, __FILE__
, __LINE__
);
169 // ... start the test fresh ...
171 // ... now build a complex object with a failure in the middle ...
173 never_reached(__FILE__
, __LINE__
);
177 // ... check the expectations ...
178 check_constructor_count(4, __FILE__
, __LINE__
);
179 check_destructor_count(4, __FILE__
, __LINE__
);
184 // ... start the test fresh ...
186 std::unique_ptr
<Aggregate
> b(new Aggregate
);
187 never_reached(__FILE__
, __LINE__
);
191 // ... check the expectations ...
192 check_constructor_count(4, __FILE__
, __LINE__
);
193 check_destructor_count(4, __FILE__
, __LINE__
);
194 check_alloc_count(1, __FILE__
, __LINE__
);
204 check_constructor_count(int expected
,
205 char const * filename
,
208 if (constructors
== expected
)
213 ACE_ERROR ((LM_ERROR
,
214 ACE_TEXT("Expected %d constructor calls, had %d -- (%s:%d)\n"),
215 expected
, constructors
, filename
, lineno
));
219 check_destructor_count(int expected
,
220 char const * filename
,
223 if (destructors
== expected
)
228 ACE_ERROR ((LM_ERROR
,
229 ACE_TEXT("Expected %d destructor calls, had %d -- (%s:%d)\n"),
230 expected
, destructors
, filename
, lineno
));
234 check_alloc_count(int expected
,
235 char const * filename
,
238 if (allocs
== expected
&& deallocs
== expected
)
243 if (allocs
!= expected
)
245 ACE_ERROR ((LM_ERROR
,
246 ACE_TEXT("Expected %d alloc calls, had %d -- (%s:%d)\n"),
247 expected
, allocs
, filename
, lineno
));
249 if (deallocs
!= expected
)
251 ACE_ERROR ((LM_ERROR
,
252 ACE_TEXT("Expected %d dealloc calls, had %d -- (%s:%d)\n"),
253 expected
, deallocs
, filename
, lineno
));
258 never_reached(char const * filename
,
262 ACE_ERROR ((LM_ERROR
,
263 ACE_TEXT("Code should not have reached (%s:%d)\n"),