[PSEH2_TEST]
[reactos.git] / rostests / tests / pseh2 / psehtest.c
1 /*
2 Copyright (c) 2008 KJK::Hyperion
3
4 Permission is hereby granted, free of charge, to any person obtaining a
5 copy of this software and associated documentation files (the "Software"),
6 to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 and/or sell copies of the Software, and to permit persons to whom the
9 Software is furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 DEALINGS IN THE SOFTWARE.
21 */
22
23 #include <pseh/pseh2.h>
24
25 #define STANDALONE
26 #include <wine/test.h>
27
28 extern void no_op(void);
29 extern int return_arg(int);
30
31 extern int return_zero(void);
32 extern int return_positive(void);
33 extern int return_negative(void);
34 extern int return_one(void);
35 extern int return_minusone(void);
36
37 extern int return_zero_2(void *);
38 extern int return_positive_2(void *);
39 extern int return_negative_2(void *);
40 extern int return_one_2(void *);
41 extern int return_minusone_2(void *);
42
43 extern int return_zero_3(int);
44 extern int return_positive_3(int);
45 extern int return_negative_3(int);
46 extern int return_one_3(int);
47 extern int return_minusone_3(int);
48
49 extern int return_zero_4(void *, int);
50 extern int return_positive_4(void *, int);
51 extern int return_negative_4(void *, int);
52 extern int return_one_4(void *, int);
53 extern int return_minusone_4(void *, int);
54
55 extern void set_positive(int *);
56
57 static int call_test(int (*)(void));
58
59 #define DEFINE_TEST(NAME_) static int NAME_(void)
60
61 /* Empty statements *///{{{
62 DEFINE_TEST(test_empty_1)
63 {
64 _SEH2_TRY { } _SEH2_EXCEPT(0) { } _SEH2_END;
65 return 1;
66 }
67
68 DEFINE_TEST(test_empty_2)
69 {
70 _SEH2_TRY { } _SEH2_EXCEPT(-1) { } _SEH2_END;
71 return 1;
72 }
73
74 DEFINE_TEST(test_empty_3)
75 {
76 _SEH2_TRY { } _SEH2_EXCEPT(1) { } _SEH2_END;
77 return 1;
78 }
79
80 DEFINE_TEST(test_empty_4)
81 {
82 _SEH2_TRY { } _SEH2_FINALLY { } _SEH2_END;
83 return 1;
84 }
85
86 DEFINE_TEST(test_empty_5)
87 {
88 _SEH2_TRY { _SEH2_TRY { } _SEH2_EXCEPT(0) { } _SEH2_END; } _SEH2_FINALLY { } _SEH2_END;
89 return 1;
90 }
91
92 DEFINE_TEST(test_empty_6)
93 {
94 _SEH2_TRY { _SEH2_TRY { } _SEH2_EXCEPT(-1) { } _SEH2_END; } _SEH2_FINALLY { } _SEH2_END;
95 return 1;
96 }
97
98 DEFINE_TEST(test_empty_7)
99 {
100 _SEH2_TRY { _SEH2_TRY { } _SEH2_EXCEPT(1) { } _SEH2_END; } _SEH2_FINALLY { } _SEH2_END;
101 return 1;
102 }
103
104 DEFINE_TEST(test_empty_8)
105 {
106 _SEH2_TRY { _SEH2_TRY { } _SEH2_FINALLY { } _SEH2_END; } _SEH2_FINALLY { } _SEH2_END;
107 return 1;
108 }
109 //}}}
110
111 /* Static exception filters *///{{{
112 DEFINE_TEST(test_execute_handler_1)
113 {
114 static int ret;
115
116 ret = return_zero();
117
118 _SEH2_TRY
119 {
120 RaiseException(0xE00DEAD0, 0, 0, NULL);
121 ret = return_zero();
122 }
123 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
124 {
125 ret = return_positive();
126 }
127 _SEH2_END;
128
129 return ret == return_positive();
130 }
131
132 DEFINE_TEST(test_continue_execution_1)
133 {
134 static int ret;
135
136 ret = return_zero();
137
138 _SEH2_TRY
139 {
140 RaiseException(0xE00DEAD0, 0, 0, NULL);
141 ret = return_positive();
142 }
143 _SEH2_EXCEPT(EXCEPTION_CONTINUE_EXECUTION)
144 {
145 ret = return_zero();
146 }
147 _SEH2_END;
148
149 return ret == return_positive();
150 }
151
152 DEFINE_TEST(test_continue_search_1)
153 {
154 static int ret;
155
156 ret = return_zero();
157
158 _SEH2_TRY
159 {
160 _SEH2_TRY
161 {
162 RaiseException(0xE00DEAD0, 0, 0, NULL);
163 ret = return_zero();
164 }
165 _SEH2_EXCEPT(EXCEPTION_CONTINUE_SEARCH)
166 {
167 ret = return_zero();
168 }
169 _SEH2_END;
170 }
171 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
172 {
173 ret = return_positive();
174 }
175 _SEH2_END;
176
177 return ret == return_positive();
178 }
179
180 DEFINE_TEST(test_execute_handler_2)
181 {
182 static int ret;
183
184 ret = return_zero();
185
186 _SEH2_TRY
187 {
188 RaiseException(0xE00DEAD0, 0, 0, NULL);
189 ret = return_zero();
190 }
191 _SEH2_EXCEPT(12345)
192 {
193 ret = return_positive();
194 }
195 _SEH2_END;
196
197 return ret == return_positive();
198 }
199
200 DEFINE_TEST(test_continue_execution_2)
201 {
202 static int ret;
203
204 ret = return_zero();
205
206 _SEH2_TRY
207 {
208 RaiseException(0xE00DEAD0, 0, 0, NULL);
209 ret = return_positive();
210 }
211 _SEH2_EXCEPT(-12345)
212 {
213 ret = return_zero();
214 }
215 _SEH2_END;
216
217 return ret == return_positive();
218 }
219 //}}}
220
221 /* Dynamic exception filters *///{{{
222 DEFINE_TEST(test_execute_handler_3)
223 {
224 static int ret;
225
226 ret = return_zero();
227
228 _SEH2_TRY
229 {
230 RaiseException(0xE00DEAD0, 0, 0, NULL);
231 ret = return_zero();
232 }
233 _SEH2_EXCEPT(return_one())
234 {
235 ret = return_positive();
236 }
237 _SEH2_END;
238
239 return ret == return_positive();
240 }
241
242 DEFINE_TEST(test_continue_execution_3)
243 {
244 static int ret;
245
246 ret = return_zero();
247
248 _SEH2_TRY
249 {
250 RaiseException(0xE00DEAD0, 0, 0, NULL);
251 ret = return_positive();
252 }
253 _SEH2_EXCEPT(return_minusone())
254 {
255 ret = return_zero();
256 }
257 _SEH2_END;
258
259 return ret == return_positive();
260 }
261
262 DEFINE_TEST(test_continue_search_2)
263 {
264 static int ret;
265
266 ret = return_zero();
267
268 _SEH2_TRY
269 {
270 _SEH2_TRY
271 {
272 RaiseException(0xE00DEAD0, 0, 0, NULL);
273 ret = return_zero();
274 }
275 _SEH2_EXCEPT(return_zero())
276 {
277 ret = return_zero();
278 }
279 _SEH2_END;
280 }
281 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
282 {
283 ret = return_positive();
284 }
285 _SEH2_END;
286
287 return ret == return_positive();
288 }
289
290 DEFINE_TEST(test_execute_handler_4)
291 {
292 static int ret;
293
294 ret = return_zero();
295
296 _SEH2_TRY
297 {
298 RaiseException(0xE00DEAD0, 0, 0, NULL);
299 ret = return_zero();
300 }
301 _SEH2_EXCEPT(return_positive())
302 {
303 ret = return_positive();
304 }
305 _SEH2_END;
306
307 return ret == return_positive();
308 }
309
310 DEFINE_TEST(test_continue_execution_4)
311 {
312 static int ret;
313
314 ret = return_zero();
315
316 _SEH2_TRY
317 {
318 RaiseException(0xE00DEAD0, 0, 0, NULL);
319 ret = return_positive();
320 }
321 _SEH2_EXCEPT(return_negative())
322 {
323 ret = return_zero();
324 }
325 _SEH2_END;
326
327 return ret == return_positive();
328 }
329 //}}}
330
331 /* Dynamic exception filters, using _SEH2_GetExceptionInformation() *///{{{
332 DEFINE_TEST(test_execute_handler_5)
333 {
334 static int ret;
335
336 ret = return_zero();
337
338 _SEH2_TRY
339 {
340 RaiseException(0xE00DEAD0, 0, 0, NULL);
341 ret = return_zero();
342 }
343 _SEH2_EXCEPT(return_one_2(_SEH2_GetExceptionInformation()))
344 {
345 ret = return_positive();
346 }
347 _SEH2_END;
348
349 return ret == return_positive();
350 }
351
352 DEFINE_TEST(test_continue_execution_5)
353 {
354 static int ret;
355
356 ret = return_zero();
357
358 _SEH2_TRY
359 {
360 RaiseException(0xE00DEAD0, 0, 0, NULL);
361 ret = return_positive();
362 }
363 _SEH2_EXCEPT(return_minusone_2(_SEH2_GetExceptionInformation()))
364 {
365 ret = return_zero();
366 }
367 _SEH2_END;
368
369 return ret == return_positive();
370 }
371
372 DEFINE_TEST(test_continue_search_3)
373 {
374 static int ret;
375
376 ret = return_positive();
377
378 _SEH2_TRY
379 {
380 _SEH2_TRY
381 {
382 RaiseException(0xE00DEAD0, 0, 0, NULL);
383 ret = return_zero();
384 }
385 _SEH2_EXCEPT(return_zero_2(_SEH2_GetExceptionInformation()))
386 {
387 ret = return_zero();
388 }
389 _SEH2_END;
390 }
391 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
392 {
393 ret = return_arg(ret);
394 }
395 _SEH2_END;
396
397 return ret == return_positive();
398 }
399
400 DEFINE_TEST(test_execute_handler_6)
401 {
402 static int ret;
403
404 ret = return_zero();
405
406 _SEH2_TRY
407 {
408 RaiseException(0xE00DEAD0, 0, 0, NULL);
409 ret = return_zero();
410 }
411 _SEH2_EXCEPT(return_positive_2(_SEH2_GetExceptionInformation()))
412 {
413 ret = return_positive();
414 }
415 _SEH2_END;
416
417 return ret == return_positive();
418 }
419
420 DEFINE_TEST(test_continue_execution_6)
421 {
422 static int ret;
423
424 ret = return_zero();
425
426 _SEH2_TRY
427 {
428 RaiseException(0xE00DEAD0, 0, 0, NULL);
429 ret = return_positive();
430 }
431 _SEH2_EXCEPT(return_negative_2(_SEH2_GetExceptionInformation()))
432 {
433 ret = return_zero();
434 }
435 _SEH2_END;
436
437 return ret == return_positive();
438 }
439 //}}}
440
441 /* Dynamic exception filters, using _SEH2_GetExceptionCode() *///{{{
442 DEFINE_TEST(test_execute_handler_7)
443 {
444 static int ret;
445
446 ret = return_zero();
447
448 _SEH2_TRY
449 {
450 RaiseException(0xE00DEAD0, 0, 0, NULL);
451 ret = return_zero();
452 }
453 _SEH2_EXCEPT(return_one_3(_SEH2_GetExceptionCode()))
454 {
455 ret = return_positive();
456 }
457 _SEH2_END;
458
459 return ret == return_positive();
460 }
461
462 DEFINE_TEST(test_continue_execution_7)
463 {
464 static int ret;
465
466 ret = return_zero();
467
468 _SEH2_TRY
469 {
470 RaiseException(0xE00DEAD0, 0, 0, NULL);
471 ret = return_positive();
472 }
473 _SEH2_EXCEPT(return_minusone_3(_SEH2_GetExceptionCode()))
474 {
475 ret = return_zero();
476 }
477 _SEH2_END;
478
479 return ret == return_positive();
480 }
481
482 DEFINE_TEST(test_continue_search_4)
483 {
484 static int ret;
485
486 ret = return_zero();
487
488 _SEH2_TRY
489 {
490 _SEH2_TRY
491 {
492 RaiseException(0xE00DEAD0, 0, 0, NULL);
493 ret = return_zero();
494 }
495 _SEH2_EXCEPT(return_zero_3(_SEH2_GetExceptionCode()))
496 {
497 ret = return_zero();
498 }
499 _SEH2_END;
500 }
501 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
502 {
503 ret = return_positive();
504 }
505 _SEH2_END;
506
507 return ret == return_positive();
508 }
509
510 DEFINE_TEST(test_execute_handler_8)
511 {
512 static int ret;
513
514 ret = return_zero();
515
516 _SEH2_TRY
517 {
518 RaiseException(0xE00DEAD0, 0, 0, NULL);
519 ret = return_zero();
520 }
521 _SEH2_EXCEPT(return_positive_3(_SEH2_GetExceptionCode()))
522 {
523 ret = return_positive();
524 }
525 _SEH2_END;
526
527 return ret == return_positive();
528 }
529
530 DEFINE_TEST(test_continue_execution_8)
531 {
532 static int ret;
533
534 ret = return_zero();
535
536 _SEH2_TRY
537 {
538 RaiseException(0xE00DEAD0, 0, 0, NULL);
539 ret = return_positive();
540 }
541 _SEH2_EXCEPT(return_negative_3(_SEH2_GetExceptionCode()))
542 {
543 ret = return_zero();
544 }
545 _SEH2_END;
546
547 return ret == return_positive();
548 }
549 //}}}
550
551 /* Dynamic exception filters, using _SEH2_GetExceptionInformation() and _SEH2_GetExceptionCode() *///{{{
552 DEFINE_TEST(test_execute_handler_9)
553 {
554 static int ret;
555
556 ret = return_zero();
557
558 _SEH2_TRY
559 {
560 RaiseException(0xE00DEAD0, 0, 0, NULL);
561 ret = return_zero();
562 }
563 _SEH2_EXCEPT(return_one_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
564 {
565 ret = return_positive();
566 }
567 _SEH2_END;
568
569 return ret == return_positive();
570 }
571
572 DEFINE_TEST(test_continue_execution_9)
573 {
574 static int ret;
575
576 ret = return_zero();
577
578 _SEH2_TRY
579 {
580 RaiseException(0xE00DEAD0, 0, 0, NULL);
581 ret = return_positive();
582 }
583 _SEH2_EXCEPT(return_minusone_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
584 {
585 ret = return_zero();
586 }
587 _SEH2_END;
588
589 return ret == return_positive();
590 }
591
592 DEFINE_TEST(test_continue_search_5)
593 {
594 static int ret;
595
596 ret = return_zero();
597
598 _SEH2_TRY
599 {
600 _SEH2_TRY
601 {
602 RaiseException(0xE00DEAD0, 0, 0, NULL);
603 ret = return_zero();
604 }
605 _SEH2_EXCEPT(return_zero_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
606 {
607 ret = return_zero();
608 }
609 _SEH2_END;
610 }
611 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
612 {
613 ret = return_positive();
614 }
615 _SEH2_END;
616
617 return ret == return_positive();
618 }
619
620 DEFINE_TEST(test_execute_handler_10)
621 {
622 static int ret;
623
624 ret = return_zero();
625
626 _SEH2_TRY
627 {
628 RaiseException(0xE00DEAD0, 0, 0, NULL);
629 ret = return_zero();
630 }
631 _SEH2_EXCEPT(return_positive_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
632 {
633 ret = return_positive();
634 }
635 _SEH2_END;
636
637 return ret == return_positive();
638 }
639
640 DEFINE_TEST(test_continue_execution_10)
641 {
642 static int ret;
643
644 ret = return_zero();
645
646 _SEH2_TRY
647 {
648 RaiseException(0xE00DEAD0, 0, 0, NULL);
649 ret = return_positive();
650 }
651 _SEH2_EXCEPT(return_negative_4(_SEH2_GetExceptionInformation(), _SEH2_GetExceptionCode()))
652 {
653 ret = return_zero();
654 }
655 _SEH2_END;
656
657 return ret == return_positive();
658 }
659 //}}}
660
661 /* Constant exception filters with side effects *///{{{
662 DEFINE_TEST(test_execute_handler_11)
663 {
664 static int ret;
665
666 ret = return_zero();
667
668 _SEH2_TRY
669 {
670 RaiseException(0xE00DEAD0, 0, 0, NULL);
671 ret = return_zero();
672 }
673 _SEH2_EXCEPT(set_positive(&ret), EXCEPTION_EXECUTE_HANDLER)
674 {
675 ret = ret ? return_positive() : return_zero();
676 }
677 _SEH2_END;
678
679 return ret == return_positive();
680 }
681
682 DEFINE_TEST(test_continue_execution_11)
683 {
684 static int ret;
685
686 ret = return_zero();
687
688 _SEH2_TRY
689 {
690 RaiseException(0xE00DEAD0, 0, 0, NULL);
691 ret = ret ? return_positive() : return_zero();
692 }
693 _SEH2_EXCEPT(set_positive(&ret), EXCEPTION_CONTINUE_EXECUTION)
694 {
695 ret = return_zero();
696 }
697 _SEH2_END;
698
699 return ret == return_positive();
700 }
701
702 DEFINE_TEST(test_continue_search_6)
703 {
704 static int ret;
705 static int ret2;
706
707 ret = return_zero();
708 ret2 = return_zero();
709
710 _SEH2_TRY
711 {
712 _SEH2_TRY
713 {
714 RaiseException(0xE00DEAD0, 0, 0, NULL);
715 ret = return_zero();
716 ret2 = return_zero();
717 }
718 _SEH2_EXCEPT(set_positive(&ret), EXCEPTION_CONTINUE_SEARCH)
719 {
720 ret = return_zero();
721 ret2 = return_zero();
722 }
723 _SEH2_END;
724 }
725 _SEH2_EXCEPT(set_positive(&ret2), EXCEPTION_EXECUTE_HANDLER)
726 {
727 ret = return_arg(ret);
728 ret2 = return_arg(ret2);
729 }
730 _SEH2_END;
731
732 return ret == return_positive() && ret2 == return_positive();
733 }
734
735 DEFINE_TEST(test_execute_handler_12)
736 {
737 static int ret;
738
739 ret = return_zero();
740
741 _SEH2_TRY
742 {
743 RaiseException(0xE00DEAD0, 0, 0, NULL);
744 ret = return_zero();
745 }
746 _SEH2_EXCEPT(set_positive(&ret), 12345)
747 {
748 ret = return_arg(ret);
749 }
750 _SEH2_END;
751
752 return ret == return_positive();
753 }
754
755 DEFINE_TEST(test_continue_execution_12)
756 {
757 static int ret;
758
759 ret = return_zero();
760
761 _SEH2_TRY
762 {
763 RaiseException(0xE00DEAD0, 0, 0, NULL);
764 ret = return_arg(ret);
765 }
766 _SEH2_EXCEPT(set_positive(&ret), -12345)
767 {
768 ret = return_zero();
769 }
770 _SEH2_END;
771
772 return ret == return_positive();
773 }
774 //}}}
775
776 /* _SEH2_LEAVE *///{{{
777 DEFINE_TEST(test_leave_1)
778 {
779 static int ret;
780
781 ret = return_zero();
782
783 _SEH2_TRY
784 {
785 ret = return_positive();
786 _SEH2_LEAVE;
787 ret = return_zero();
788 }
789 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
790 {
791 ret = return_zero();
792 }
793 _SEH2_END;
794
795 return ret == return_positive();
796 }
797
798 DEFINE_TEST(test_leave_2)
799 {
800 static int ret;
801
802 ret = return_zero();
803
804 _SEH2_TRY
805 {
806 ret = return_positive();
807 _SEH2_LEAVE;
808
809 RaiseException(0xE00DEAD0, 0, 0, NULL);
810 ret = return_zero();
811 }
812 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
813 {
814 ret = return_zero();
815 }
816 _SEH2_END;
817
818 return ret == return_positive();
819 }
820
821 DEFINE_TEST(test_leave_3)
822 {
823 static int ret;
824
825 ret = return_zero();
826
827 _SEH2_TRY
828 {
829 ret = return_positive();
830
831 if(return_one())
832 _SEH2_LEAVE;
833
834 ret = return_zero();
835 }
836 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
837 {
838 ret = return_zero();
839 }
840 _SEH2_END;
841
842 return ret == return_positive();
843 }
844
845 DEFINE_TEST(test_leave_4)
846 {
847 static int ret;
848
849 ret = return_zero();
850
851 _SEH2_TRY
852 {
853 int i;
854 int n = return_one() + return_one();
855
856 for(i = return_zero(); i < n; ++ i)
857 {
858 if(i == return_one())
859 {
860 ret = return_positive();
861 _SEH2_LEAVE;
862 }
863 }
864
865 ret = return_zero();
866 }
867 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
868 {
869 ret = return_zero();
870 }
871 _SEH2_END;
872
873 return ret == return_positive();
874 }
875
876 DEFINE_TEST(test_leave_5)
877 {
878 static int ret;
879
880 ret = return_zero();
881
882 _SEH2_TRY
883 {
884 switch(return_one())
885 {
886 case 0: ret = return_zero();
887 case 1: ret = return_positive(); _SEH2_LEAVE;
888 case 2: ret = return_zero();
889 }
890
891 ret = return_zero();
892 }
893 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
894 {
895 ret = return_zero();
896 }
897 _SEH2_END;
898
899 return ret == return_positive();
900 }
901
902 DEFINE_TEST(test_leave_6)
903 {
904 static int ret;
905
906 ret = return_zero();
907
908 _SEH2_TRY
909 {
910 _SEH2_TRY
911 {
912 _SEH2_LEAVE;
913 }
914 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
915 {
916 ret = return_zero();
917 }
918 _SEH2_END;
919
920 ret = return_positive();
921 }
922 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
923 {
924 ret = return_zero();
925 }
926 _SEH2_END;
927
928 return ret == return_positive();
929 }
930 //}}}
931
932 /* _SEH2_YIELD() *///{{{
933 static
934 int test_yield_1_helper(void)
935 {
936 _SEH2_TRY
937 {
938 _SEH2_YIELD(return return_positive());
939 }
940 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
941 {
942 _SEH2_YIELD(return return_zero());
943 }
944 _SEH2_END;
945
946 return return_zero();
947 }
948
949 DEFINE_TEST(test_yield_1)
950 {
951 return test_yield_1_helper() == return_positive();
952 }
953
954 static
955 int test_yield_2_helper(void)
956 {
957 _SEH2_TRY
958 {
959 RaiseException(0xE00DEAD0, 0, 0, NULL);
960 _SEH2_YIELD(return return_zero());
961 }
962 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
963 {
964 _SEH2_YIELD(return return_positive());
965 }
966 _SEH2_END;
967
968 return return_zero();
969 }
970
971 DEFINE_TEST(test_yield_2)
972 {
973 return test_yield_2_helper() == return_positive();
974 }
975
976 static
977 int test_yield_3_helper(void)
978 {
979 _SEH2_TRY
980 {
981 _SEH2_TRY
982 {
983 _SEH2_YIELD(return return_positive());
984 }
985 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
986 {
987 _SEH2_YIELD(return return_zero());
988 }
989 _SEH2_END;
990
991 _SEH2_YIELD(return return_zero());
992 }
993 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
994 {
995 _SEH2_YIELD(return return_zero());
996 }
997 _SEH2_END;
998
999 return return_zero();
1000 }
1001
1002 DEFINE_TEST(test_yield_3)
1003 {
1004 return test_yield_3_helper() == return_positive();
1005 }
1006
1007 static
1008 int test_yield_4_helper(void)
1009 {
1010 _SEH2_TRY
1011 {
1012 _SEH2_TRY
1013 {
1014 RaiseException(0xE00DEAD0, 0, 0, NULL);
1015 _SEH2_YIELD(return return_zero());
1016 }
1017 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1018 {
1019 _SEH2_YIELD(return return_positive());
1020 }
1021 _SEH2_END;
1022
1023 _SEH2_YIELD(return return_zero());
1024 }
1025 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1026 {
1027 _SEH2_YIELD(return return_zero());
1028 }
1029 _SEH2_END;
1030
1031 return return_zero();
1032 }
1033
1034 DEFINE_TEST(test_yield_4)
1035 {
1036 return test_yield_4_helper() == return_positive();
1037 }
1038
1039 static int test_yield_5_ret;
1040
1041 static
1042 int test_yield_5_helper(void)
1043 {
1044 test_yield_5_ret = return_zero();
1045
1046 _SEH2_TRY
1047 {
1048 _SEH2_YIELD(return return_positive());
1049 }
1050 _SEH2_FINALLY
1051 {
1052 test_yield_5_ret = return_positive();
1053 }
1054 _SEH2_END;
1055
1056 return return_zero();
1057 }
1058
1059 DEFINE_TEST(test_yield_5)
1060 {
1061 return test_yield_5_helper() == return_positive() && test_yield_5_ret == return_positive();
1062 }
1063
1064 int test_yield_6_ret;
1065
1066 static
1067 int test_yield_6_helper(void)
1068 {
1069 test_yield_6_ret = return_zero();
1070
1071 _SEH2_TRY
1072 {
1073 _SEH2_TRY
1074 {
1075 _SEH2_YIELD(return return_positive());
1076 }
1077 _SEH2_FINALLY
1078 {
1079 test_yield_6_ret = return_positive();
1080 }
1081 _SEH2_END;
1082 }
1083 _SEH2_FINALLY
1084 {
1085 test_yield_6_ret += return_one();
1086 }
1087 _SEH2_END;
1088
1089 return return_zero();
1090 }
1091
1092 DEFINE_TEST(test_yield_6)
1093 {
1094 return test_yield_6_helper() == return_positive() && test_yield_6_ret == return_positive() + return_one();
1095 }
1096 //}}}
1097
1098 /* Termination blocks *///{{{
1099 DEFINE_TEST(test_finally_1)
1100 {
1101 static int ret;
1102
1103 ret = return_zero();
1104
1105 _SEH2_TRY
1106 {
1107 ret = return_arg(ret);
1108 }
1109 _SEH2_FINALLY
1110 {
1111 ret = return_positive();
1112 }
1113 _SEH2_END;
1114
1115 return ret == return_positive();
1116 }
1117
1118 DEFINE_TEST(test_finally_2)
1119 {
1120 static int ret;
1121
1122 ret = return_zero();
1123
1124 _SEH2_TRY
1125 {
1126 ret = return_arg(ret);
1127 _SEH2_LEAVE;
1128 }
1129 _SEH2_FINALLY
1130 {
1131 ret = return_positive();
1132 }
1133 _SEH2_END;
1134
1135 return ret == return_positive();
1136 }
1137
1138 DEFINE_TEST(test_finally_3)
1139 {
1140 static int ret;
1141
1142 ret = return_zero();
1143
1144 _SEH2_TRY
1145 {
1146 ret = return_arg(ret);
1147 _SEH2_YIELD(goto leave);
1148 }
1149 _SEH2_FINALLY
1150 {
1151 ret = return_positive();
1152 }
1153 _SEH2_END;
1154
1155 leave:
1156 return ret == return_positive();
1157 }
1158
1159 static int test_finally_4_ret;
1160
1161 static int test_finally_4_helper(void)
1162 {
1163 test_finally_4_ret = return_zero();
1164
1165 _SEH2_TRY
1166 {
1167 test_finally_4_ret = return_arg(test_finally_4_ret);
1168 _SEH2_YIELD(return return_positive());
1169 }
1170 _SEH2_FINALLY
1171 {
1172 test_finally_4_ret = return_positive();
1173 }
1174 _SEH2_END;
1175
1176 return return_zero();
1177 }
1178
1179 DEFINE_TEST(test_finally_4)
1180 {
1181 return test_finally_4_helper() == return_positive() && test_finally_4_ret;
1182 }
1183
1184 DEFINE_TEST(test_finally_5)
1185 {
1186 static int ret;
1187
1188 ret = return_zero();
1189
1190 _SEH2_TRY
1191 {
1192 _SEH2_TRY
1193 {
1194 RaiseException(0xE00DEAD0, 0, 0, NULL);
1195 ret = return_zero();
1196 }
1197 _SEH2_FINALLY
1198 {
1199 ret = return_positive();
1200 }
1201 _SEH2_END;
1202 }
1203 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1204 {
1205 ret = return_arg(ret);
1206 }
1207 _SEH2_END;
1208
1209 return ret == return_positive();
1210 }
1211
1212 DEFINE_TEST(test_finally_6)
1213 {
1214 static int ret;
1215
1216 ret = return_zero();
1217
1218 _SEH2_TRY
1219 {
1220 _SEH2_TRY
1221 {
1222 ret = return_arg(ret);
1223 }
1224 _SEH2_FINALLY
1225 {
1226 if(ret == return_zero())
1227 ret = return_positive();
1228 }
1229 _SEH2_END;
1230 }
1231 _SEH2_FINALLY
1232 {
1233 if(ret == return_positive())
1234 ret = return_positive() + return_one();
1235 }
1236 _SEH2_END;
1237
1238 return ret == return_positive() + return_one();
1239 }
1240
1241 DEFINE_TEST(test_finally_7)
1242 {
1243 static int ret;
1244
1245 ret = return_zero();
1246
1247 _SEH2_TRY
1248 {
1249 _SEH2_TRY
1250 {
1251 ret = return_arg(ret);
1252 _SEH2_LEAVE;
1253 }
1254 _SEH2_FINALLY
1255 {
1256 if(ret == return_zero())
1257 ret = return_positive();
1258 }
1259 _SEH2_END;
1260 }
1261 _SEH2_FINALLY
1262 {
1263 if(ret == return_positive())
1264 ret = return_positive() + return_one();
1265 }
1266 _SEH2_END;
1267
1268 return ret == return_positive() + return_one();
1269 }
1270
1271 DEFINE_TEST(test_finally_8)
1272 {
1273 static int ret;
1274
1275 ret = return_zero();
1276
1277 _SEH2_TRY
1278 {
1279 _SEH2_TRY
1280 {
1281 ret = return_arg(ret);
1282 _SEH2_YIELD(goto leave);
1283 }
1284 _SEH2_FINALLY
1285 {
1286 if(ret == return_zero())
1287 ret = return_positive();
1288 }
1289 _SEH2_END;
1290 }
1291 _SEH2_FINALLY
1292 {
1293 if(ret == return_positive())
1294 ret = return_positive() + return_one();
1295 }
1296 _SEH2_END;
1297
1298 leave:
1299 return ret == return_positive() + return_one();
1300 }
1301
1302 static int test_finally_9_ret;
1303
1304 static int test_finally_9_helper(void)
1305 {
1306 test_finally_9_ret = return_zero();
1307
1308 _SEH2_TRY
1309 {
1310 _SEH2_TRY
1311 {
1312 test_finally_9_ret = return_arg(test_finally_9_ret);
1313 _SEH2_YIELD(return return_positive());
1314 }
1315 _SEH2_FINALLY
1316 {
1317 if(test_finally_9_ret == return_zero())
1318 test_finally_9_ret = return_positive();
1319 }
1320 _SEH2_END;
1321 }
1322 _SEH2_FINALLY
1323 {
1324 if(test_finally_9_ret == return_positive())
1325 test_finally_9_ret = return_positive() + return_one();
1326 }
1327 _SEH2_END;
1328
1329 return return_zero();
1330 }
1331
1332 DEFINE_TEST(test_finally_9)
1333 {
1334 return test_finally_9_helper() == return_positive() && test_finally_9_ret == return_positive() + return_one();
1335 }
1336
1337 DEFINE_TEST(test_finally_10)
1338 {
1339 static int ret;
1340
1341 ret = return_zero();
1342
1343 _SEH2_TRY
1344 {
1345 _SEH2_TRY
1346 {
1347 _SEH2_TRY
1348 {
1349 RaiseException(0xE00DEAD0, 0, 0, NULL);
1350 ret = return_zero();
1351 }
1352 _SEH2_FINALLY
1353 {
1354 if(ret == return_zero())
1355 ret = return_positive();
1356 }
1357 _SEH2_END;
1358 }
1359 _SEH2_FINALLY
1360 {
1361 if(ret == return_positive())
1362 ret = return_positive() + return_one();
1363 }
1364 _SEH2_END;
1365 }
1366 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1367 {
1368 ret = return_arg(ret);
1369 }
1370 _SEH2_END;
1371
1372 return ret == return_positive() + return_one();
1373 }
1374
1375 DEFINE_TEST(test_finally_11)
1376 {
1377 static int ret;
1378
1379 ret = return_zero();
1380
1381 _SEH2_TRY
1382 {
1383 _SEH2_TRY
1384 {
1385 _SEH2_TRY
1386 {
1387 ret = return_arg(ret);
1388 }
1389 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1390 {
1391 ret = return_zero();
1392 }
1393 _SEH2_END;
1394 }
1395 _SEH2_FINALLY
1396 {
1397 ret = return_positive();
1398 RaiseException(0xE00DEAD0, 0, 0, NULL);
1399 ret = return_zero();
1400 }
1401 _SEH2_END;
1402 }
1403 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1404 {
1405 if(ret == return_positive())
1406 ret += return_one();
1407 }
1408 _SEH2_END;
1409
1410 return ret == return_positive() + return_one();
1411 }
1412
1413 DEFINE_TEST(test_finally_12)
1414 {
1415 static int ret;
1416
1417 ret = return_zero();
1418
1419 _SEH2_TRY
1420 {
1421 _SEH2_TRY
1422 {
1423 _SEH2_TRY
1424 {
1425 ret = return_arg(ret);
1426 }
1427 _SEH2_FINALLY
1428 {
1429 ret = return_positive();
1430 RaiseException(0xE00DEAD0, 0, 0, NULL);
1431 ret = return_zero();
1432 }
1433 _SEH2_END;
1434 }
1435 _SEH2_FINALLY
1436 {
1437 if(ret == return_positive())
1438 ret += return_one();
1439 }
1440 _SEH2_END;
1441 }
1442 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1443 {
1444 if(ret == return_positive() + return_one())
1445 ret += return_one();
1446 }
1447 _SEH2_END;
1448
1449 return ret == return_positive() + return_one() + return_one();
1450 }
1451
1452 static int test_finally_13_ret;
1453
1454 static
1455 void test_finally_13_helper(void)
1456 {
1457 test_finally_13_ret = return_zero();
1458
1459 _SEH2_TRY
1460 {
1461 _SEH2_TRY
1462 {
1463 test_finally_13_ret = return_positive();
1464 _SEH2_YIELD(return);
1465 test_finally_13_ret = return_zero();
1466 }
1467 _SEH2_FINALLY
1468 {
1469 if(test_finally_13_ret == return_positive())
1470 test_finally_13_ret += return_one();
1471 }
1472 _SEH2_END;
1473 }
1474 _SEH2_FINALLY
1475 {
1476 if(test_finally_13_ret == return_positive() + return_one())
1477 test_finally_13_ret += return_one();
1478
1479 RaiseException(0xE00DEAD0, 0, 0, NULL);
1480 test_finally_13_ret = return_zero();
1481 }
1482 _SEH2_END;
1483
1484 test_finally_13_ret = return_zero();
1485 }
1486
1487 DEFINE_TEST(test_finally_13)
1488 {
1489 static int ret;
1490
1491 ret = return_zero();
1492
1493 _SEH2_TRY
1494 {
1495 ret = return_arg(ret);
1496 test_finally_13_helper();
1497 ret = return_zero();
1498 }
1499 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1500 {
1501 ret = return_positive();
1502 }
1503 _SEH2_END;
1504
1505 return ret == return_positive() && test_finally_13_ret == return_positive() + return_one() + return_one();
1506 }
1507
1508 static int test_finally_14_ret;
1509
1510 static
1511 void test_finally_14_helper(void)
1512 {
1513 test_finally_14_ret = return_zero();
1514
1515 _SEH2_TRY
1516 {
1517 _SEH2_TRY
1518 {
1519 _SEH2_TRY
1520 {
1521 test_finally_14_ret = return_positive();
1522 RaiseException(0xE00DEAD0, 0, 0, NULL);
1523 test_finally_14_ret = return_zero();
1524 }
1525 _SEH2_FINALLY
1526 {
1527 if(test_finally_14_ret == return_positive())
1528 test_finally_14_ret += return_one();
1529 }
1530 _SEH2_END;
1531 }
1532 _SEH2_FINALLY
1533 {
1534 if(test_finally_14_ret == return_positive() + return_one())
1535 test_finally_14_ret += return_one();
1536
1537 RaiseException(0xE00DEAD0, 0, 0, NULL);
1538 test_finally_14_ret = return_zero();
1539 }
1540 _SEH2_END;
1541 }
1542 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1543 {
1544 if(test_finally_14_ret == return_positive() + return_one() + return_one())
1545 test_finally_14_ret += return_one();
1546 }
1547 _SEH2_END;
1548
1549 test_finally_14_ret = return_arg(test_finally_14_ret);
1550 }
1551
1552 DEFINE_TEST(test_finally_14)
1553 {
1554 static int ret;
1555
1556 ret = return_zero();
1557
1558 _SEH2_TRY
1559 {
1560 ret = return_arg(ret);
1561 test_finally_14_helper();
1562 ret = return_positive();
1563 }
1564 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1565 {
1566 ret = return_zero();
1567 }
1568 _SEH2_END;
1569
1570 return ret == return_positive() && test_finally_14_ret == return_positive() + return_one() + return_one() + return_one();
1571 }
1572 //}}}
1573
1574 /* _SEH2_GetExceptionInformation() *///{{{
1575 static
1576 int verify_xpointers(struct _EXCEPTION_POINTERS * ep, DWORD code, DWORD flags, DWORD argc, const ULONG_PTR * argv, int * ret, int filter)
1577 {
1578 *ret =
1579 ep &&
1580 ep->ExceptionRecord &&
1581 ep->ContextRecord &&
1582 ep->ExceptionRecord->ExceptionCode == code &&
1583 ep->ExceptionRecord->ExceptionFlags == flags &&
1584 ep->ExceptionRecord->NumberParameters == argc &&
1585 (argv || !argc) &&
1586 memcmp(ep->ExceptionRecord->ExceptionInformation, argv, sizeof(argv[0]) * argc) == 0;
1587
1588 if(*ret)
1589 *ret = return_positive();
1590
1591 return filter;
1592 }
1593
1594 DEFINE_TEST(test_xpointers_1)
1595 {
1596 static int ret;
1597
1598 ret = return_zero();
1599
1600 _SEH2_TRY
1601 {
1602 RaiseException(0xE00DEAD0, 0, 0, NULL);
1603 }
1604 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 0, NULL, &ret, EXCEPTION_EXECUTE_HANDLER))
1605 {
1606 ret = return_arg(ret);
1607 }
1608 _SEH2_END;
1609
1610 return ret == return_positive();
1611 }
1612
1613 DEFINE_TEST(test_xpointers_2)
1614 {
1615 static int ret;
1616
1617 ret = return_zero();
1618
1619 _SEH2_TRY
1620 {
1621 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, NULL);
1622 }
1623 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, NULL, &ret, EXCEPTION_EXECUTE_HANDLER))
1624 {
1625 ret = return_arg(ret);
1626 }
1627 _SEH2_END;
1628
1629 return ret == return_positive();
1630 }
1631
1632 DEFINE_TEST(test_xpointers_3)
1633 {
1634 static int ret;
1635 static const ULONG_PTR args[] = { 1, 2, 12345 };
1636
1637 ret = return_zero();
1638
1639 _SEH2_TRY
1640 {
1641 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, args);
1642 }
1643 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, args, &ret, EXCEPTION_EXECUTE_HANDLER))
1644 {
1645 ret = return_arg(ret);
1646 }
1647 _SEH2_END;
1648
1649 return ret == return_positive();
1650 }
1651
1652 DEFINE_TEST(test_xpointers_4)
1653 {
1654 static int ret;
1655 static const ULONG_PTR args[] = { 1, 2, 12345 };
1656
1657 ret = return_zero();
1658
1659 _SEH2_TRY
1660 {
1661 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 1, args);
1662 }
1663 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 1, args, &ret, EXCEPTION_EXECUTE_HANDLER))
1664 {
1665 ret = return_arg(ret);
1666 }
1667 _SEH2_END;
1668
1669 return ret == return_positive();
1670 }
1671
1672 DEFINE_TEST(test_xpointers_5)
1673 {
1674 static int ret;
1675 static const ULONG_PTR args[] = { 1, 2, 12345 };
1676
1677 ret = return_zero();
1678
1679 _SEH2_TRY
1680 {
1681 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 2, args);
1682 }
1683 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 2, args, &ret, EXCEPTION_EXECUTE_HANDLER))
1684 {
1685 ret = return_arg(ret);
1686 }
1687 _SEH2_END;
1688
1689 return ret == return_positive();
1690 }
1691
1692 DEFINE_TEST(test_xpointers_6)
1693 {
1694 static int ret;
1695 static const ULONG_PTR args[] = { 1, 2, 12345 };
1696
1697 ret = return_zero();
1698
1699 _SEH2_TRY
1700 {
1701 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 3, args);
1702 }
1703 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 3, args, &ret, EXCEPTION_EXECUTE_HANDLER))
1704 {
1705 ret = return_arg(ret);
1706 }
1707 _SEH2_END;
1708
1709 return ret == return_positive();
1710 }
1711
1712 DEFINE_TEST(test_xpointers_7)
1713 {
1714 static int ret;
1715
1716 ret = return_zero();
1717
1718 _SEH2_TRY
1719 {
1720 RaiseException(0xE00DEAD0, 0, 0, NULL);
1721 ret = return_arg(ret);
1722 }
1723 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 0, NULL, &ret, EXCEPTION_CONTINUE_EXECUTION))
1724 {
1725 ret = return_zero();
1726 }
1727 _SEH2_END;
1728
1729 return ret == return_positive();
1730 }
1731
1732 DEFINE_TEST(test_xpointers_8)
1733 {
1734 static int ret;
1735 static const ULONG_PTR args[] = { 1, 2, 12345 };
1736
1737 ret = return_zero();
1738
1739 _SEH2_TRY
1740 {
1741 RaiseException(0xE00DEAD0, 0, 0, args);
1742 ret = return_arg(ret);
1743 }
1744 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 0, args, &ret, EXCEPTION_CONTINUE_EXECUTION))
1745 {
1746 ret = return_zero();
1747 }
1748 _SEH2_END;
1749
1750 return ret == return_positive();
1751 }
1752
1753 DEFINE_TEST(test_xpointers_9)
1754 {
1755 static int ret;
1756 static const ULONG_PTR args[] = { 1, 2, 12345 };
1757
1758 ret = return_zero();
1759
1760 _SEH2_TRY
1761 {
1762 RaiseException(0xE00DEAD0, 0, 1, args);
1763 ret = return_arg(ret);
1764 }
1765 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 1, args, &ret, EXCEPTION_CONTINUE_EXECUTION))
1766 {
1767 ret = return_zero();
1768 }
1769 _SEH2_END;
1770
1771 return ret == return_positive();
1772 }
1773
1774 DEFINE_TEST(test_xpointers_10)
1775 {
1776 static int ret;
1777 static const ULONG_PTR args[] = { 1, 2, 12345 };
1778
1779 ret = return_zero();
1780
1781 _SEH2_TRY
1782 {
1783 RaiseException(0xE00DEAD0, 0, 2, args);
1784 ret = return_arg(ret);
1785 }
1786 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 2, args, &ret, EXCEPTION_CONTINUE_EXECUTION))
1787 {
1788 ret = return_zero();
1789 }
1790 _SEH2_END;
1791
1792 return ret == return_positive();
1793 }
1794
1795 DEFINE_TEST(test_xpointers_11)
1796 {
1797 static int ret;
1798 static const ULONG_PTR args[] = { 1, 2, 12345 };
1799
1800 ret = return_zero();
1801
1802 _SEH2_TRY
1803 {
1804 RaiseException(0xE00DEAD0, 0, 3, args);
1805 ret = return_arg(ret);
1806 }
1807 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, 0, 3, args, &ret, EXCEPTION_CONTINUE_EXECUTION))
1808 {
1809 ret = return_zero();
1810 }
1811 _SEH2_END;
1812
1813 return ret == return_positive();
1814 }
1815
1816 DEFINE_TEST(test_xpointers_12)
1817 {
1818 static int ret;
1819
1820 ret = return_zero();
1821
1822 _SEH2_TRY
1823 {
1824 _SEH2_TRY
1825 {
1826 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, NULL);
1827 }
1828 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, NULL, &ret, EXCEPTION_CONTINUE_SEARCH))
1829 {
1830 ret = return_zero();
1831 }
1832 _SEH2_END;
1833 }
1834 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1835 {
1836 ret = return_arg(ret);
1837 }
1838 _SEH2_END;
1839
1840 return ret == return_positive();
1841 }
1842
1843 DEFINE_TEST(test_xpointers_13)
1844 {
1845 static int ret;
1846 static const ULONG_PTR args[] = { 1, 2, 12345 };
1847
1848 ret = return_zero();
1849
1850 _SEH2_TRY
1851 {
1852 _SEH2_TRY
1853 {
1854 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, args);
1855 }
1856 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 0, args, &ret, EXCEPTION_CONTINUE_SEARCH))
1857 {
1858 ret = return_zero();
1859 }
1860 _SEH2_END;
1861 }
1862 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1863 {
1864 ret = return_arg(ret);
1865 }
1866 _SEH2_END;
1867
1868 return ret == return_positive();
1869 }
1870
1871 DEFINE_TEST(test_xpointers_14)
1872 {
1873 static int ret;
1874 static const ULONG_PTR args[] = { 1, 2, 12345 };
1875
1876 ret = return_zero();
1877
1878 _SEH2_TRY
1879 {
1880 _SEH2_TRY
1881 {
1882 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 1, args);
1883 }
1884 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 1, args, &ret, EXCEPTION_CONTINUE_SEARCH))
1885 {
1886 ret = return_zero();
1887 }
1888 _SEH2_END;
1889 }
1890 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1891 {
1892 ret = return_arg(ret);
1893 }
1894 _SEH2_END;
1895
1896 return ret == return_positive();
1897 }
1898
1899 DEFINE_TEST(test_xpointers_15)
1900 {
1901 static int ret;
1902 static const ULONG_PTR args[] = { 1, 2, 12345 };
1903
1904 ret = return_zero();
1905
1906 _SEH2_TRY
1907 {
1908 _SEH2_TRY
1909 {
1910 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 2, args);
1911 }
1912 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 2, args, &ret, EXCEPTION_CONTINUE_SEARCH))
1913 {
1914 ret = return_zero();
1915 }
1916 _SEH2_END;
1917 }
1918 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1919 {
1920 ret = return_arg(ret);
1921 }
1922 _SEH2_END;
1923
1924 return ret == return_positive();
1925 }
1926
1927 DEFINE_TEST(test_xpointers_16)
1928 {
1929 static int ret;
1930 static const ULONG_PTR args[] = { 1, 2, 12345 };
1931
1932 ret = return_zero();
1933
1934 _SEH2_TRY
1935 {
1936 _SEH2_TRY
1937 {
1938 RaiseException(0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 3, args);
1939 }
1940 _SEH2_EXCEPT(verify_xpointers(_SEH2_GetExceptionInformation(), 0xE00DEAD0, EXCEPTION_NONCONTINUABLE, 3, args, &ret, EXCEPTION_CONTINUE_SEARCH))
1941 {
1942 ret = return_zero();
1943 }
1944 _SEH2_END;
1945 }
1946 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1947 {
1948 ret = return_arg(ret);
1949 }
1950 _SEH2_END;
1951
1952 return ret == return_positive();
1953 }
1954 //}}}
1955
1956 /* _SEH2_GetExceptionCode() *///{{{
1957 static
1958 int verify_xcode(int code, int xcode, int * ret, int filter)
1959 {
1960 *ret = code == xcode;
1961
1962 if(*ret)
1963 *ret = return_positive();
1964
1965 return filter;
1966 }
1967
1968 DEFINE_TEST(test_xcode_1)
1969 {
1970 static int ret;
1971
1972 ret = return_zero();
1973
1974 _SEH2_TRY
1975 {
1976 RaiseException(0xE00DEAD0, 0, 0, NULL);
1977 ret = return_zero();
1978 }
1979 _SEH2_EXCEPT(verify_xcode(_SEH2_GetExceptionCode(), 0xE00DEAD0, &ret, EXCEPTION_EXECUTE_HANDLER))
1980 {
1981 ret = return_arg(ret);
1982 }
1983 _SEH2_END;
1984
1985 return ret == return_positive();
1986 }
1987
1988 DEFINE_TEST(test_xcode_2)
1989 {
1990 static int ret;
1991
1992 ret = return_zero();
1993
1994 _SEH2_TRY
1995 {
1996 RaiseException(0xE00DEAD0, 0, 0, NULL);
1997 ret = return_arg(ret);
1998 }
1999 _SEH2_EXCEPT(verify_xcode(_SEH2_GetExceptionCode(), 0xE00DEAD0, &ret, EXCEPTION_CONTINUE_EXECUTION))
2000 {
2001 ret = return_zero();
2002 }
2003 _SEH2_END;
2004
2005 return ret == return_positive();
2006 }
2007
2008 DEFINE_TEST(test_xcode_3)
2009 {
2010 static int ret;
2011
2012 ret = return_zero();
2013
2014 _SEH2_TRY
2015 {
2016 _SEH2_TRY
2017 {
2018 RaiseException(0xE00DEAD0, 0, 0, NULL);
2019 ret = return_zero();
2020 }
2021 _SEH2_EXCEPT(verify_xcode(_SEH2_GetExceptionCode(), 0xE00DEAD0, &ret, EXCEPTION_CONTINUE_SEARCH))
2022 {
2023 ret = return_zero();
2024 }
2025 _SEH2_END;
2026 }
2027 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2028 {
2029 ret = return_arg(ret);
2030 }
2031 _SEH2_END;
2032
2033 return ret == return_positive();
2034 }
2035 //}}}
2036
2037 /* _SEH2_AbnormalTermination() *///{{{
2038 DEFINE_TEST(test_abnorm_1)
2039 {
2040 static int ret;
2041
2042 ret = return_zero();
2043
2044 _SEH2_TRY
2045 {
2046 ret = return_arg(ret);
2047 }
2048 _SEH2_FINALLY
2049 {
2050 ret = _SEH2_AbnormalTermination() ? return_zero() : return_positive();
2051 }
2052 _SEH2_END;
2053
2054 return ret == return_positive();
2055 }
2056
2057 DEFINE_TEST(test_abnorm_2)
2058 {
2059 static int ret;
2060
2061 ret = return_zero();
2062
2063 _SEH2_TRY
2064 {
2065 _SEH2_LEAVE;
2066 }
2067 _SEH2_FINALLY
2068 {
2069 ret = _SEH2_AbnormalTermination() ? return_zero() : return_positive();
2070 }
2071 _SEH2_END;
2072
2073 return ret == return_positive();
2074 }
2075
2076 DEFINE_TEST(test_abnorm_3)
2077 {
2078 static int ret;
2079
2080 ret = return_zero();
2081
2082 _SEH2_TRY
2083 {
2084 _SEH2_YIELD(goto leave);
2085 }
2086 _SEH2_FINALLY
2087 {
2088 ret = _SEH2_AbnormalTermination() ? return_positive() : return_zero();
2089 }
2090 _SEH2_END;
2091
2092 leave:
2093 return ret == return_positive();
2094 }
2095
2096 DEFINE_TEST(test_abnorm_4)
2097 {
2098 static int ret;
2099
2100 ret = return_zero();
2101
2102 _SEH2_TRY
2103 {
2104 _SEH2_TRY
2105 {
2106 RaiseException(0xE00DEAD0, 0, 0, NULL);
2107 ret = return_zero();
2108 }
2109 _SEH2_FINALLY
2110 {
2111 ret = _SEH2_AbnormalTermination() ? return_positive() : return_zero();
2112 }
2113 _SEH2_END;
2114 }
2115 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2116 {
2117 ret = return_arg(ret);
2118 }
2119 _SEH2_END;
2120
2121 return ret == return_positive();
2122 }
2123
2124 DEFINE_TEST(test_abnorm_5)
2125 {
2126 static int ret;
2127
2128 ret = return_zero();
2129
2130 _SEH2_TRY
2131 {
2132 _SEH2_TRY
2133 {
2134 ret = return_arg(ret);
2135 }
2136 _SEH2_FINALLY
2137 {
2138 ret = _SEH2_AbnormalTermination() ? return_zero() : return_positive();
2139 }
2140 _SEH2_END;
2141 }
2142 _SEH2_FINALLY
2143 {
2144 ret = ret == return_positive() && !_SEH2_AbnormalTermination() ? return_positive() + return_one() : ret;
2145 }
2146 _SEH2_END;
2147
2148 return ret == return_positive() + return_one();
2149 }
2150
2151 DEFINE_TEST(test_abnorm_6)
2152 {
2153 static int ret;
2154
2155 ret = return_zero();
2156
2157 _SEH2_TRY
2158 {
2159 _SEH2_TRY
2160 {
2161 _SEH2_LEAVE;
2162 }
2163 _SEH2_FINALLY
2164 {
2165 ret = _SEH2_AbnormalTermination() ? return_zero() : return_positive();
2166 }
2167 _SEH2_END;
2168 }
2169 _SEH2_FINALLY
2170 {
2171 ret = ret == return_positive() && !_SEH2_AbnormalTermination() ? return_positive() + return_one() : ret;
2172 }
2173 _SEH2_END;
2174
2175 return ret == return_positive() + return_one();
2176 }
2177
2178 DEFINE_TEST(test_abnorm_7)
2179 {
2180 static int ret;
2181
2182 ret = return_zero();
2183
2184 _SEH2_TRY
2185 {
2186 _SEH2_TRY
2187 {
2188 _SEH2_YIELD(goto leave);
2189 }
2190 _SEH2_FINALLY
2191 {
2192 ret = _SEH2_AbnormalTermination() ? return_positive() : return_zero();
2193 }
2194 _SEH2_END;
2195 }
2196 _SEH2_FINALLY
2197 {
2198 ret = ret == return_positive() && _SEH2_AbnormalTermination() ? return_positive() + return_one() : ret;
2199 }
2200 _SEH2_END;
2201
2202 leave:
2203 return ret == return_positive() + return_one();
2204 }
2205
2206 DEFINE_TEST(test_abnorm_8)
2207 {
2208 static int ret;
2209
2210 ret = return_zero();
2211
2212 _SEH2_TRY
2213 {
2214 _SEH2_TRY
2215 {
2216 _SEH2_TRY
2217 {
2218 RaiseException(0xE00DEAD0, 0, 0, NULL);
2219 ret = return_zero();
2220 }
2221 _SEH2_FINALLY
2222 {
2223 ret = _SEH2_AbnormalTermination() ? return_positive() : return_zero();
2224 }
2225 _SEH2_END;
2226 }
2227 _SEH2_FINALLY
2228 {
2229 ret = ret == return_positive() && _SEH2_AbnormalTermination() ? return_positive() + return_one() : ret;
2230 }
2231 _SEH2_END;
2232 }
2233 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2234 {
2235 ret = return_arg(ret);
2236 }
2237 _SEH2_END;
2238
2239 return ret == return_positive() + return_one();
2240 }
2241 //}}}
2242
2243 /* Use of local variables from _SEH2_EXCEPT(...) and _SEH2_FINALLY { ... } *///{{{
2244 DEFINE_TEST(test_nested_locals_1)
2245 {
2246 int var1 = return_one();
2247
2248 _SEH2_TRY
2249 {
2250 RaiseException(0xE00DEAD0, 0, 0, 0);
2251 }
2252 _SEH2_EXCEPT((var1 = (var1 == return_one() ? return_positive() : var1)), EXCEPTION_EXECUTE_HANDLER)
2253 {
2254 if(var1 == return_positive())
2255 var1 = return_positive() + 1;
2256 }
2257 _SEH2_END;
2258
2259 return var1 == return_positive() + 1;
2260 }
2261
2262 DEFINE_TEST(test_nested_locals_2)
2263 {
2264 int var1 = return_positive();
2265
2266 _SEH2_TRY
2267 {
2268 }
2269 _SEH2_FINALLY
2270 {
2271 if(var1 == return_positive())
2272 var1 = return_positive() + 1;
2273 }
2274 _SEH2_END;
2275
2276 return var1 == return_positive() + 1;
2277 }
2278
2279 DEFINE_TEST(test_nested_locals_3)
2280 {
2281 int var1 = return_zero();
2282
2283 _SEH2_TRY
2284 {
2285 _SEH2_TRY
2286 {
2287 var1 = return_one();
2288 RaiseException(0xE00DEAD0, 0, 0, 0);
2289 }
2290 _SEH2_FINALLY
2291 {
2292 if(var1 == return_one())
2293 var1 = return_positive();
2294 }
2295 _SEH2_END;
2296 }
2297 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2298 {
2299 if(var1 == return_positive())
2300 var1 = return_positive() + 1;
2301 }
2302 _SEH2_END;
2303
2304 return var1 == return_positive() + 1;
2305 }
2306 //}}}
2307
2308 /* System support *///{{{
2309 // TODO
2310 //}}}
2311
2312 /* CPU faults *///{{{
2313 // TODO
2314 //}}}
2315
2316 /* Past bugs, to detect regressions *///{{{
2317 /* #4004: volatile registers clobbered when catching across frames (originally misreported) *///{{{
2318 static
2319 void test_bug_4004_helper_1(void)
2320 {
2321 int i1, i2, i3;
2322
2323 i1 = return_positive();
2324 i2 = return_positive();
2325 i3 = return_positive();
2326 (void)return_arg(i1 + i2 + i3);
2327
2328 _SEH2_TRY
2329 {
2330 RaiseException(0xE00DEAD0, 0, 0, NULL);
2331 }
2332 _SEH2_FINALLY
2333 {
2334 }
2335 _SEH2_END;
2336 }
2337
2338 static
2339 void test_bug_4004_helper_2(void)
2340 {
2341 _SEH2_TRY
2342 {
2343 test_bug_4004_helper_1();
2344 }
2345 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2346 {
2347 }
2348 _SEH2_END;
2349 }
2350
2351 DEFINE_TEST(test_bug_4004)
2352 {
2353 int i1, i2, i3;
2354
2355 i1 = return_positive();
2356 i2 = return_positive();
2357 i3 = return_positive();
2358
2359 test_bug_4004_helper_2();
2360
2361 return return_arg(i1) + return_arg(i2) + return_arg(i3) == return_positive() * 3;
2362 }
2363 //}}}
2364
2365 /* #4663: *///{{{
2366 DEFINE_TEST(test_bug_4663)
2367 {
2368 int i1, i2;
2369
2370 i1 = return_positive();
2371 i2 = return_positive();
2372
2373 _SEH2_TRY
2374 {
2375 _SEH2_TRY
2376 {
2377 RaiseException(0xE00DEAD0, 0, 0, 0);
2378 }
2379 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2380 {
2381 if (i1 == return_positive())
2382 {
2383 i1 = return_positive() + 1;
2384 }
2385 }
2386 _SEH2_END;
2387
2388 if (i1 == return_positive() + 1)
2389 {
2390 i1 = return_negative();
2391 RaiseException(0xE00DEAD0, 0, 0, 0);
2392 }
2393 }
2394 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2395 {
2396 i2 = return_negative();
2397 }
2398 _SEH2_END;
2399
2400 return ((i1 == return_negative()) && (i2 == return_negative()));
2401 }
2402 //}}}
2403 //}}}
2404
2405 DEFINE_TEST(test_unvolatile)
2406 {
2407 int val = 0;
2408
2409 _SEH2_TRY
2410 {
2411 val = return_one();
2412 *((char*)0xc0000000) = 0;
2413 }
2414 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2415 {
2416 val = val + 3;
2417 }
2418 _SEH2_END;
2419
2420 return (val == 4);
2421 }
2422
2423 DEFINE_TEST(test_unvolatile_2)
2424 {
2425 int val = 0;
2426
2427 _SEH2_TRY
2428 {
2429 val = 1;
2430 *((char*)0xc0000000) = 0;
2431 val = 2;
2432 }
2433 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2434 {
2435 val = val + 3;
2436 }
2437 _SEH2_END;
2438
2439 return (val == 3) || (val == 4) || (val == 5);
2440 }
2441
2442 DEFINE_TEST(test_unvolatile_3)
2443 {
2444 int register val1 = 0, val2 = 0;
2445
2446 _SEH2_TRY
2447 {
2448 val1 = 1;
2449
2450 _SEH2_TRY
2451 {
2452 val2 = 1;
2453 *((char*)0xc0000000) = 0;
2454 val2 = 2;
2455 }
2456 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2457 {
2458 val2 |= 4;
2459 }
2460 _SEH2_END;
2461
2462 val1 = 2;
2463 *((int*)0xc0000000) = 1;
2464 val1 = 3;
2465 }
2466 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2467 {
2468 val1 = val1 * val2;
2469 }
2470 _SEH2_END;
2471
2472 /* The expected case */
2473 if ((val1 == 10) && (val2 == 5))
2474 return TRUE;
2475
2476 /* The compiler can optimize away "val1 = 1" and "val1 = 2" and
2477 only use the last "val1 = 3", in this case val1 is still 0
2478 when the outer exception handler kicks in */
2479 if ((val1 == 0) && (val2 == 5))
2480 return TRUE;
2481
2482 /* Same as above, but this time val2 optimized away */
2483 if (((val1 == 8) && (val2 == 4)) ||
2484 ((val1 == 0) && (val2 == 4)))
2485 return TRUE;
2486
2487 return FALSE;
2488 }
2489
2490 DEFINE_TEST(test_finally_goto)
2491 {
2492 volatile int val = 0;
2493
2494 _SEH2_TRY
2495 {
2496 val |= 1;
2497 _SEH2_TRY
2498 {
2499 val |= 2;
2500 goto next;
2501 }
2502 _SEH2_FINALLY
2503 {
2504 val |= 4;
2505 *((char*)0xdeadc0de) = 0;
2506 val |= 8;
2507 }
2508 _SEH2_END;
2509
2510 val |= 16;
2511 next:
2512 val |= 32;
2513 *((char*)0xdeadc0de) = 0;
2514 val |= 64;
2515 }
2516 _SEH2_EXCEPT(1)
2517 {
2518 val |= 128;
2519 }
2520 _SEH2_END;
2521
2522 return (val == (128|4|2|1));
2523 }
2524
2525 DEFINE_TEST(test_nested_exception)
2526 {
2527 volatile int val = 0;
2528
2529 _SEH2_TRY
2530 {
2531 val |= 1;
2532 _SEH2_TRY
2533 {
2534 val |= 2;
2535 *((char*)0xdeadc0de) = 0;
2536 val |= 4;
2537 }
2538 _SEH2_EXCEPT(1)
2539 {
2540 val |= 8;
2541 *((char*)0xdeadc0de) = 0;
2542 val |= 16;
2543 }
2544 _SEH2_END;
2545
2546 val |= 32;
2547 *((char*)0xdeadc0de) = 0;
2548 val |= 64;
2549 }
2550 _SEH2_EXCEPT(1)
2551 {
2552 val |= 128;
2553 }
2554 _SEH2_END;
2555
2556 return (val == (1|2|8|128));
2557 }
2558
2559 static
2560 LONG WINAPI unhandled_exception(PEXCEPTION_POINTERS ExceptionInfo)
2561 {
2562 trace("unhandled exception %08lX thrown from %p\n", ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress);
2563 return EXCEPTION_CONTINUE_SEARCH;
2564 }
2565
2566 #if defined(_M_IX86)
2567 struct volatile_context
2568 {
2569 void * esp;
2570 void * ebp;
2571 void * ebx;
2572 void * esi;
2573 void * edi;
2574 };
2575 #else
2576 struct volatile_context
2577 {
2578 int _ignore;
2579 };
2580 #endif
2581
2582 static
2583 DECLSPEC_NOINLINE
2584 int sanity_check(int ret, struct volatile_context * before, struct volatile_context * after)
2585 {
2586 if(ret && memcmp(before, after, sizeof(before)))
2587 {
2588 trace("volatile context corrupted\n");
2589 return 0;
2590 }
2591
2592 return ret;
2593 }
2594
2595 #ifndef _PSEH3_H_
2596 static
2597 int passthrough_handler(struct _EXCEPTION_RECORD * e, void * f, struct _CONTEXT * c, void * d)
2598 {
2599 return ExceptionContinueSearch;
2600 }
2601 #endif
2602
2603 static
2604 DECLSPEC_NOINLINE
2605 int call_test(int (* func)(void))
2606 {
2607 static int ret;
2608 static struct volatile_context before, after;
2609 static LPTOP_LEVEL_EXCEPTION_FILTER prev_unhandled_exception;
2610 #ifndef _PSEH3_H_
2611 static _SEH2Registration_t * prev_frame;
2612 _SEH2Registration_t passthrough_frame;
2613 #endif
2614
2615 prev_unhandled_exception = SetUnhandledExceptionFilter(&unhandled_exception);
2616
2617 #if defined(_X86_) && !defined(_PSEH3_H_)
2618 prev_frame = (_SEH2Registration_t *)__readfsdword(0);
2619 passthrough_frame.SER_Prev = prev_frame;
2620 passthrough_frame.SER_Handler = passthrough_handler;
2621 __writefsdword(0, (unsigned long)&passthrough_frame);
2622 #endif
2623
2624 #if defined(__GNUC__) && defined(__i386__)
2625 __asm__ __volatile__
2626 (
2627 "mov %%esp, 0x00 + %c[before]\n"
2628 "mov %%ebp, 0x04 + %c[before]\n"
2629 "mov %%ebx, 0x08 + %c[before]\n"
2630 "mov %%esi, 0x0c + %c[before]\n"
2631 "mov %%edi, 0x10 + %c[before]\n"
2632 "call *%[test]\n"
2633 "mov %%esp, 0x00 + %c[after]\n"
2634 "mov %%ebp, 0x04 + %c[after]\n"
2635 "mov %%ebx, 0x08 + %c[after]\n"
2636 "mov %%esi, 0x0c + %c[after]\n"
2637 "mov %%edi, 0x10 + %c[after]\n"
2638 "push %[after]\n"
2639 "push %[before]\n"
2640 "push %[ret]\n"
2641 "call %c[sanity_check]\n"
2642 "pop %%ecx\n"
2643 "pop %%ecx\n"
2644 "pop %%ecx\n" :
2645 [ret] "=a" (ret) :
2646 [test] "r" (func), [before] "i" (&before), [after] "i" (&after), [sanity_check] "i" (&sanity_check) :
2647 "ebx", "ecx", "edx", "esi", "edi", "flags", "memory"
2648 );
2649 #else
2650 ret = func();
2651 #endif
2652
2653 #if defined(_X86_) && !defined(_PSEH3_H_)
2654 if((_SEH2Registration_t *)__readfsdword(0) != &passthrough_frame || passthrough_frame.SER_Prev != prev_frame)
2655 {
2656 trace("exception registration list corrupted\n");
2657 ret = 0;
2658 }
2659
2660 __writefsdword(0, (unsigned long)prev_frame);
2661 #endif
2662
2663 SetUnhandledExceptionFilter(prev_unhandled_exception);
2664 return ret;
2665 }
2666
2667 DEFINE_TEST(test_PSEH3_bug)
2668 {
2669 volatile int count = 0;
2670 int dummy = 0;
2671
2672 _SEH2_TRY
2673 {
2674 if (count++ == 0)
2675 {
2676 *(volatile int*)0x12345678 = 0x12345678;
2677 }
2678 }
2679 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2680 {
2681 dummy = 0;
2682 }
2683 _SEH2_END;
2684
2685 (void)dummy;
2686 return (count == 1);
2687 }
2688
2689 #define USE_TEST_NAME_(NAME_) # NAME_
2690 #define USE_TEST_NAME(NAME_) USE_TEST_NAME_(NAME_)
2691 #define USE_TEST(NAME_) { USE_TEST_NAME(NAME_), NAME_ }
2692
2693 struct subtest
2694 {
2695 const char * name;
2696 int (* func)(void);
2697 };
2698
2699 void testsuite_syntax(void)
2700 {
2701 const struct subtest testsuite[] =
2702 {
2703 USE_TEST(test_empty_1),
2704 USE_TEST(test_empty_2),
2705 USE_TEST(test_empty_3),
2706 USE_TEST(test_empty_4),
2707 USE_TEST(test_empty_5),
2708 USE_TEST(test_empty_6),
2709 USE_TEST(test_empty_7),
2710 USE_TEST(test_empty_8),
2711
2712 USE_TEST(test_execute_handler_1),
2713 USE_TEST(test_continue_execution_1),
2714 USE_TEST(test_continue_search_1),
2715 USE_TEST(test_execute_handler_2),
2716 USE_TEST(test_continue_execution_2),
2717
2718 USE_TEST(test_execute_handler_3),
2719 USE_TEST(test_continue_execution_3),
2720 USE_TEST(test_continue_search_2),
2721 USE_TEST(test_execute_handler_4),
2722 USE_TEST(test_continue_execution_4),
2723
2724 USE_TEST(test_execute_handler_5),
2725 USE_TEST(test_continue_execution_5),
2726 USE_TEST(test_continue_search_3),
2727 USE_TEST(test_execute_handler_6),
2728 USE_TEST(test_continue_execution_6),
2729
2730 USE_TEST(test_execute_handler_7),
2731 USE_TEST(test_continue_execution_7),
2732 USE_TEST(test_continue_search_4),
2733 USE_TEST(test_execute_handler_8),
2734 USE_TEST(test_continue_execution_8),
2735
2736 USE_TEST(test_execute_handler_9),
2737 USE_TEST(test_continue_execution_9),
2738 USE_TEST(test_continue_search_5),
2739 USE_TEST(test_execute_handler_10),
2740 USE_TEST(test_continue_execution_10),
2741
2742 USE_TEST(test_execute_handler_11),
2743 USE_TEST(test_continue_execution_11),
2744 USE_TEST(test_continue_search_6),
2745 USE_TEST(test_execute_handler_12),
2746 USE_TEST(test_continue_execution_12),
2747
2748 USE_TEST(test_leave_1),
2749 USE_TEST(test_leave_2),
2750 USE_TEST(test_leave_3),
2751 USE_TEST(test_leave_4),
2752 USE_TEST(test_leave_5),
2753 USE_TEST(test_leave_6),
2754
2755 USE_TEST(test_yield_1),
2756 USE_TEST(test_yield_2),
2757 USE_TEST(test_yield_3),
2758 USE_TEST(test_yield_4),
2759 USE_TEST(test_yield_5),
2760 USE_TEST(test_yield_6),
2761
2762 USE_TEST(test_finally_1),
2763 USE_TEST(test_finally_2),
2764 USE_TEST(test_finally_3),
2765 USE_TEST(test_finally_4),
2766 USE_TEST(test_finally_5),
2767 USE_TEST(test_finally_6),
2768 USE_TEST(test_finally_7),
2769 USE_TEST(test_finally_8),
2770 USE_TEST(test_finally_9),
2771 USE_TEST(test_finally_10),
2772 USE_TEST(test_finally_11),
2773 USE_TEST(test_finally_12),
2774 USE_TEST(test_finally_13),
2775 USE_TEST(test_finally_14),
2776
2777 USE_TEST(test_xpointers_1),
2778 USE_TEST(test_xpointers_2),
2779 USE_TEST(test_xpointers_3),
2780 USE_TEST(test_xpointers_4),
2781 USE_TEST(test_xpointers_5),
2782 USE_TEST(test_xpointers_6),
2783 USE_TEST(test_xpointers_7),
2784 USE_TEST(test_xpointers_8),
2785 USE_TEST(test_xpointers_9),
2786 USE_TEST(test_xpointers_10),
2787 USE_TEST(test_xpointers_11),
2788 USE_TEST(test_xpointers_12),
2789 USE_TEST(test_xpointers_13),
2790 USE_TEST(test_xpointers_14),
2791 USE_TEST(test_xpointers_15),
2792 USE_TEST(test_xpointers_16),
2793
2794 USE_TEST(test_xcode_1),
2795 USE_TEST(test_xcode_2),
2796 USE_TEST(test_xcode_3),
2797
2798 USE_TEST(test_abnorm_1),
2799 USE_TEST(test_abnorm_2),
2800 USE_TEST(test_abnorm_3),
2801 USE_TEST(test_abnorm_4),
2802 USE_TEST(test_abnorm_5),
2803 USE_TEST(test_abnorm_6),
2804 USE_TEST(test_abnorm_7),
2805 USE_TEST(test_abnorm_8),
2806
2807 USE_TEST(test_nested_locals_1),
2808 USE_TEST(test_nested_locals_2),
2809 USE_TEST(test_nested_locals_3),
2810
2811 USE_TEST(test_bug_4004),
2812 USE_TEST(test_bug_4663),
2813
2814 USE_TEST(test_unvolatile),
2815 USE_TEST(test_unvolatile_2),
2816 USE_TEST(test_unvolatile_3),
2817 USE_TEST(test_finally_goto),
2818 USE_TEST(test_nested_exception),
2819 USE_TEST(test_PSEH3_bug),
2820 };
2821
2822 size_t i;
2823
2824 for(i = 0; i < sizeof(testsuite) / sizeof(testsuite[0]); ++ i)
2825 ok(call_test(testsuite[i].func), "%s failed\n", testsuite[i].name);
2826 }
2827
2828 const struct test winetest_testlist[] = {
2829 { "pseh2_syntax", testsuite_syntax },
2830 { 0, 0 }
2831 };
2832
2833 /* EOF */