ReactOS  0.4.15-dev-1386-g5cb9f87
ehthrow.cxx
Go to the documentation of this file.
1 // Copyright (c) Microsoft. All rights reserved.
2 // Licensed under the MIT license. See LICENSE file in the project root for
3 // full license information.
4 
5 /*
6  Tests some throw and rethrow situations (mostly CRT a test)
7 */
8 
9 
10 #include <stdlib.h>
11 #include <stdio.h>
12 
13 
14 #define FALSE 0
15 #define TRUE 1
16 #define NO_CTOR_THROW 1
17 #define NO_DTOR_THROW 2
18 
19 
20 int Object[100];
22 int MaxTest = 10;
24 int Fail;
25 
26 
27 void FAIL(int i)
28 {
29  printf("FAILED on %d\n", i);
30  Fail++;
31 }
32 
33 void dealloc(int i, int no_throw)
34 {
35  /* Make sure i is valid, and object exists */
36  if(i<0 || i>=MaxObjectCount || !Object[i])
37  FAIL(i);
38 
39  Object[i] = 0;
40 }
41 
42 void alloc(int i, int no_throw)
43 {
46 
47  /* Object already exists? */
48  if(Object[i]) FAIL(i);
49 
50  Object[i] = 1;
51 }
52 
53 class B
54 {
55 public:
56  int i;
57  int flag;
58  B();
59  B(int);
60  B(const B &b);
61  ~B();
62 };
63 
65 {
67  printf("B ctor. i = %d\n", i);
68  alloc(i, FALSE);
69 }
70 
71 B::B(int f)
72 {
74  flag = f;
75  printf("B ctor. i = %d\n", i);
77 }
78 
79 B::B(const B &b)
80 {
82  printf("B copy ctor. i = %d\n", i);
83  alloc(i, FALSE);
84 }
85 
87 {
88  printf("B dtor. i = %d\n", i);
90 }
91 
92 class A
93 {
94 public:
95  int i;
96  A();
97  A(int)
98  {
100  printf("A(int) ctor. i = %d\n", i);
101  alloc(i, FALSE);
102  }
103  A operator+(A a);
104  A(const A &a)
105  {
106  /* Try objects in ctor */
108 
110  printf("A copy ctor. i = %d\n", i);
111  alloc(i, FALSE);
112  }
113 
114  ~A(){
115  /* Try objects in dtor */
117 
118  printf("A dtor. i = %d\n", i);
119  dealloc(i, FALSE);
120  };
121 };
122 
124 {
126  printf("A ctor. i = %d\n", i);
127  alloc(i, FALSE);
128 }
129 
131 {
132  printf("A%d + A%d\n", i, a.i);
133  return A();
134 }
135 
136 void Throwa(A a)
137 {
138  printf("Throwing\n");
139  throw a;
140 }
141 
142 void bar()
143 {
144  A a;
145 
146  Throwa(a);
147 }
148 
149 void foobar()
150 {
151  B b;
152  bar();
153 }
154 
155 // Somehow, inlining this causes different unwinding order..
156 
157 __declspec(noinline) void Rethrow2()
158 {
159  A a;
160  printf("Rethrowing\n");
161  throw;
162 }
163 
164 #pragma inline_depth(0)
165 void Rethrow()
166 {
167  Rethrow2();
168 }
169 #pragma inline_depth()
170 
171 void foobar2()
172 {
173  B b;
174 
175  try{
176  A a;
177  bar();
178  }catch(A a){
179  printf("In catch;\n");
180  Rethrow();
181  }
182 }
183 
184 void foobar3()
185 {
186  B b;
187 
188  try{
189  A a;
190  bar();
191  }catch(A a){
192  printf("In catch\n");
193  A a2;
194 
195  printf("Throwing new a\n");
196  throw a2;
197  }
198 }
199 
200 void foobar4()
201 {
202  B b;
203 
204  try{
205  B b;
206  try{
207  A a1, a2;
208  try {
209  A a1, a2;
210  foobar2();
211  }catch(A a){
212  printf("In catch #1\n");
213  B b;
214  printf("Rethrowing\n");
215  throw;
216  }
217  }catch(A &a){
218  printf("In catch #2\n");
219  A a2;
220 
221  printf("Throwing new a\n");
222  throw a;
223  }
224  }catch(A a){
225  printf("In catch #3\n");
226  B b;
227  printf("Rethrowing\n");
228  throw;
229  }
230 }
231 
232 __declspec(noinline) void throw_B_2()
233 {
234  B b;
235  printf("Throwing a new b\n");
236  throw b;
237 }
238 
239 #pragma inline_depth(0)
240 void throw_B()
241 {
242  throw_B_2();
243 }
244 #pragma inline_depth()
245 
246 
247 void foobar5()
248 {
249  try {
250  B b1;
251  try {
252  B b2;
253  try {
254  B b3;
255  foobar();
256  }catch(B b){
257  printf("In catch #1\n");
258  FAIL(-1);
259  }
260  FAIL(-1);
261  }catch(A a){
262  A a2;
263  printf("In catch #2\n");
264  throw_B();
265  }
266  FAIL(-1);
267  }catch(B b){
268  printf("In catch #3\n");
269  printf("Throwing a new a\n");
270  throw A();
271  }
272  FAIL(-1);
273 }
274 
275 
276 /* Simple throw with unwinds */
277 void test1()
278 {
279  A a;
280  foobar();
281 }
282 
283 /* Throw followed by a rethrow */
284 void test2()
285 {
286  A a;
287  foobar2();
288 }
289 
290 /* Throw followed by a new throw */
291 void test3()
292 {
293  A a;
294  foobar3();
295 }
296 
297 /* Nested trys with rethrow/throw/rethrow */
298 void test4()
299 {
300  A a;
301  foobar4();
302 }
303 
304 /* Makes sure a new throw skips appropriate unwound frames. */
305 void test5()
306 {
307  A a;
308  foobar5();
309 }
310 
311 // Tests 3 level of new throw
312 void test6()
313 {
314  try{
315  B b1;
316  try{
317  B b2;
318  try{
319  B b3;
320  printf("Throwing a b\n");
321  throw(b3);
322  }catch(B b){
323  B b4;
324  printf("In catch #1\n");
325  printf("Throwing a new b\n");
326  throw(b4);
327  }
328  FAIL(-1);
329  }catch(B b){
330  B b5;
331  printf("In catch #2\n");
332  printf("Throwing a new b\n");
333  throw(b5);
334  }
335  FAIL(-1);
336  }catch(B b){
337  A a1;
338  printf("In catch #3\n");
339  printf("Throwing a new a\n");
340  throw(a1);
341  }
342  FAIL(-1);
343 }
344 
345 // Testing try/catch inside a catch
346 void test7()
347 {
348  B b1;
349  try{
350  B b2;
351  try{
352  B b3;
353 
354  printf("Throwing a b\n");
355  throw(B());
356  }catch(B b){
357  B b4;
358  printf("In catch #1\n");
359  try{
360  B b5;
361  printf("Rethrowing b\n");
362  throw;
363  }catch(B b){
364  B b5;
365  printf("In catch #1 of catch#1\n");
366  printf("Rethrowing b\n");
367  throw;
368  }
369  }
370  }catch(B b){
371  B b6;
372  printf("In catch #2\n");
373  printf("Throwing a new A\n");
374  throw(A());
375  }
376 }
377 
378 void ThrowB()
379 {
380  B b;
381 
382  throw(B());
383 }
384 
385 void bar8()
386 {
387  try{
388  B b5;
389  printf("Rethrowing b\n");
390  Rethrow();
391  }catch(B b){
392  B b5;
393  printf("In catch #1 of catch#1\n");
394  printf("Rethrowing b\n");
395  Rethrow();
396  }
397 }
398 
399 void foo8()
400 {
401  B b;
402  try{
403  B b3;
404 
405  printf("Throwing a b\n");
406  ThrowB();
407  }catch(B b){
408  B b4;
409  printf("In catch #1\n");
410  bar8();
411  }
412 }
413 
414 // Testing call to try/catch function inside a catch
415 void test8()
416 {
417  B b1;
418  try{
419  B b2;
420  foo8();
421  }catch(B b){
422  B b6;
423  printf("In catch #2\n");
424  printf("Throwing a new A\n");
425  throw(A());
426  }
427 }
428 
429 void foo9()
430 {
431  try {
432  puts("Rethrow");
433  throw;
434  }catch(...){
435  puts("In catch #2");
436  }
437 }
438 
439 void test9()
440 {
441  try{
442  B b;
443  puts("Throwing B");
444  throw b;
445  }catch(...){
446  puts("In catch #1");
447  foo9();
448  }
449  puts("End of test9, throwing a A");
450  throw A();
451 }
452 
453 void foo10()
454 {
455  try {
456  puts("Throwing a new B()");
457  throw B();
458  }catch(...){
459  puts("In catch #2");
460  }
461 }
462 
463 void test10()
464 {
465  try{
466  B b;
467  puts("Throwing B");
468  throw b;
469  }catch(...){
470  puts("In catch #1");
471  foo10();
472  }
473  puts("End of test10, throwing a A");
474  throw A();
475 }
476 
477 int main()
478 {
479  int i;
480 
481  /* Call test(), with a different ctor/dtor throwing each time */
482  for(Test = 1; Test <= MaxTest; Test++) {
483 
485 
486  printf("\nTest #%d\n", Test);
487 
488  try {
489  switch(Test){
490  case 1:
491  test1();
492  break;
493  case 2:
494  test2();
495  break;
496  case 3:
497  test3();
498  break;
499  case 4:
500  test4();
501  break;
502  case 5:
503  test5();
504  break;
505  case 6:
506  test6();
507  break;
508  case 7:
509  test7();
510  break;
511  case 8:
512  test8();
513  break;
514  case 9:
515  test9();
516  break;
517  case 10:
518  test10();
519  break;
520  }
521 
522  FAIL(-1);
523 
524  }catch(A a){
525  printf("In main's catch\n");
526  }catch(...){
527  FAIL(-1);
528  }
529 
530  /* Any objects which didn't get dtor'd? */
531  for(i = 0; i < MaxObjectCount; i++) {
532  if(Object[i]) {
533  FAIL(i);
534  Object[i] = 0;
535  }
536  }
537 
538  printf("\n");
539  }
540 
541  printf("\n");
542  if(Fail)
543  printf("FAILED %d tests\n", Fail);
544  else
545  printf("Passed\n");
546 
547 }
Definition: ttei1.cpp:15
~B()
Definition: ehthrow.cxx:86
A()
Definition: ehthrow.cxx:123
Definition: ehthrow.cxx:53
void ThrowB()
Definition: ehthrow.cxx:378
void test8()
Definition: ehthrow.cxx:415
#define NO_DTOR_THROW
Definition: ehthrow.cxx:17
void bar8()
Definition: ehthrow.cxx:385
void dealloc(int i, int no_throw)
Definition: ehthrow.cxx:33
int main()
Definition: ehthrow.cxx:477
__declspec(noinline) void Rethrow2()
Definition: ehthrow.cxx:157
void throw_B()
Definition: ehthrow.cxx:240
A(int)
Definition: ehthrow.cxx:97
void foobar()
Definition: ehthrow.cxx:149
#define FALSE
Definition: ehthrow.cxx:14
int i
Definition: ehthrow.cxx:56
void test4()
Definition: ehthrow.cxx:298
B()
Definition: ehthrow.cxx:64
int Fail
Definition: ehthrow.cxx:24
Definition: ehthrow.cxx:92
void foobar2()
Definition: ehthrow.cxx:171
#define noinline
Definition: types.h:60
#define A(row, col)
#define a
Definition: ke_i.h:78
int i
Definition: ehthrow.cxx:95
static CRYPT_DATA_BLOB b1[]
Definition: msg.c:573
void Rethrow()
Definition: ehthrow.cxx:165
void FAIL(int i)
Definition: ehthrow.cxx:27
void bar()
Definition: ehthrow.cxx:142
#define b
Definition: ke_i.h:79
void alloc(int i, int no_throw)
Definition: ehthrow.cxx:42
void test10()
Definition: ehthrow.cxx:463
void foobar3()
Definition: ehthrow.cxx:184
void test6()
Definition: ehthrow.cxx:312
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
int MaxObjectCount
Definition: ehthrow.cxx:23
void foobar4()
Definition: ehthrow.cxx:200
static const struct update_accum a2
Definition: msg.c:586
void test1()
Definition: ehthrow.cxx:277
A(const A &a)
Definition: ehthrow.cxx:104
void foo8()
Definition: ehthrow.cxx:399
void test3()
Definition: ehthrow.cxx:291
void test7()
Definition: ehthrow.cxx:346
int flag
Definition: ehthrow.cxx:57
void foo9()
Definition: ehthrow.cxx:429
~A()
Definition: ehthrow.cxx:114
int puts(const char *string)
Definition: crtsupp.c:23
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
void foo10()
Definition: ehthrow.cxx:453
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
A operator+(A a)
Definition: ehthrow.cxx:130
static CRYPT_DATA_BLOB b3[]
Definition: msg.c:592
void test5()
Definition: ehthrow.cxx:305
void test2()
Definition: ehthrow.cxx:284
#define f
Definition: ke_i.h:83
void foobar5()
Definition: ehthrow.cxx:247
void test9()
Definition: ehthrow.cxx:439
#define B(row, col)
void Throwa(A a)
Definition: ehthrow.cxx:136
static CRYPT_DATA_BLOB b2[]
Definition: msg.c:582
static CRYPT_DATA_BLOB b4
Definition: msg.c:2284
static const struct update_accum a1
Definition: msg.c:578
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define NO_CTOR_THROW
Definition: ehthrow.cxx:16
int Test
Definition: ehthrow.cxx:21
int MaxTest
Definition: ehthrow.cxx:22
int CurrentObjectNumber
Definition: ehthrow.cxx:21
#define printf
Definition: config.h:203