ntdll: Remove dead increments (clang).
[wine] / dlls / msvcp90 / exception.c
1 /*
2  * Copyright 2010 Piotr Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "config.h"
20
21 #include <stdarg.h>
22
23 #include "msvcp90.h"
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wine/debug.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(msvcp90);
29
30 /* dlls/msvcrt/cppexcept.h */
31 typedef void (*cxx_copy_ctor)(void);
32
33 /* complete information about a C++ type */
34 typedef struct __cxx_type_info
35 {
36     UINT             flags;        /* flags (see CLASS_* flags below) */
37     const type_info *type_info;    /* C++ type info */
38     this_ptr_offsets offsets;      /* offsets for computing the this pointer */
39     unsigned int     size;         /* object size */
40     cxx_copy_ctor    copy_ctor;    /* copy constructor */
41 } cxx_type_info;
42 #define CLASS_IS_SIMPLE_TYPE          1
43 #define CLASS_HAS_VIRTUAL_BASE_CLASS  4
44
45 /* table of C++ types that apply for a given object */
46 typedef struct __cxx_type_info_table
47 {
48     UINT                 count;     /* number of types */
49     const cxx_type_info *info[3];   /* variable length, we declare it large enough for static RTTI */
50 } cxx_type_info_table;
51
52 /* type information for an exception object */
53 typedef struct __cxx_exception_type
54 {
55     UINT                       flags;            /* TYPE_FLAG flags */
56     void                     (*destructor)(void);/* exception object destructor */
57     void* /*cxx_exc_custom_handler*/ custom_handler;   /* custom handler for this exception */
58     const cxx_type_info_table *type_info_table;  /* list of types for this exception object */
59 } cxx_exception_type;
60
61 void WINAPI _CxxThrowException(exception*,const cxx_exception_type*);
62
63 /* vtables */
64
65 #ifdef _WIN64
66
67 #define __ASM_EXCEPTION_VTABLE(name) \
68     __ASM_VTABLE(name, "\t.quad " THISCALL_NAME(MSVCP_what_exception) )
69
70 #define __ASM_EXCEPTION_STRING_VTABLE(name) \
71     __ASM_VTABLE(name, "\t.quad " THISCALL_NAME(MSVCP_logic_error_what) )
72
73 #else
74
75 #define __ASM_EXCEPTION_VTABLE(name) \
76     __ASM_VTABLE(name, "\t.long " THISCALL_NAME(MSVCP_what_exception) )
77
78 #define __ASM_EXCEPTION_STRING_VTABLE(name) \
79     __ASM_VTABLE(name, "\t.long " THISCALL_NAME(MSVCP_logic_error_what) )
80
81 #endif /* _WIN64 */
82
83 extern const vtable_ptr MSVCP_bad_alloc_vtable;
84 extern const vtable_ptr MSVCP_logic_error_vtable;
85 extern const vtable_ptr MSVCP_length_error_vtable;
86 extern const vtable_ptr MSVCP_out_of_range_vtable;
87 extern const vtable_ptr MSVCP_invalid_argument_vtable;
88
89 /* exception class data */
90 static type_info exception_type_info = {
91     NULL, /* set by set_exception_vtable */
92     NULL,
93     ".?AVexception@std@@"
94 };
95
96 DEFINE_THISCALL_WRAPPER(MSVCP_exception_ctor, 8)
97 exception* __thiscall MSVCP_exception_ctor(exception *this, const char **name)
98 {
99     TRACE("(%p %s)\n", this, *name);
100
101     this->vtable = exception_type_info.vtable;
102     if(*name) {
103         unsigned int name_len = strlen(*name) + 1;
104         this->name = malloc(name_len);
105         memcpy(this->name, *name, name_len);
106         this->do_free = TRUE;
107     } else {
108         this->name = NULL;
109         this->do_free = FALSE;
110     }
111     return this;
112 }
113
114 DEFINE_THISCALL_WRAPPER(MSVCP_exception_copy_ctor,8)
115 exception* __thiscall MSVCP_exception_copy_ctor(exception *this, const exception *rhs)
116 {
117     TRACE("(%p,%p)\n", this, rhs);
118
119     if(!rhs->do_free) {
120         this->vtable = exception_type_info.vtable;
121         this->name = rhs->name;
122         this->do_free = FALSE;
123     } else
124         MSVCP_exception_ctor(this, (const char**)&rhs->name);
125     TRACE("name = %s\n", this->name);
126     return this;
127 }
128
129 DEFINE_THISCALL_WRAPPER(MSVCP_exception_dtor,4)
130 void __thiscall MSVCP_exception_dtor(exception *this)
131 {
132     TRACE("(%p)\n", this);
133     this->vtable = exception_type_info.vtable;
134     if(this->do_free)
135         free(this->name);
136 }
137
138 static const rtti_base_descriptor exception_rtti_base_descriptor = {
139     &exception_type_info,
140     0,
141     { 0, -1, 0 },
142     0
143 };
144
145 static const cxx_type_info exception_cxx_type_info = {
146     0,
147     &exception_type_info,
148     { 0, -1, 0 },
149     sizeof(exception),
150     (cxx_copy_ctor)THISCALL(MSVCP_exception_dtor)
151 };
152
153 static const cxx_type_info_table exception_cxx_type_table = {
154     1,
155     {
156         &exception_cxx_type_info,
157         NULL,
158         NULL
159     }
160 };
161
162 static const cxx_exception_type exception_cxx_type = {
163     0,
164     (cxx_copy_ctor)THISCALL(MSVCP_exception_copy_ctor),
165     NULL,
166     &exception_cxx_type_table
167 };
168
169 void set_exception_vtable(void)
170 {
171     HMODULE hmod = GetModuleHandleA("msvcrt.dll");
172     exception_type_info.vtable = (void*)GetProcAddress(hmod, "??_7exception@@6B@");
173 }
174
175 /* bad_alloc class data */
176 typedef exception bad_alloc;
177
178 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_ctor, 8)
179 bad_alloc* __thiscall MSVCP_bad_alloc_ctor(bad_alloc *this, const char **name)
180 {
181     TRACE("%p %s\n", this, *name);
182     MSVCP_exception_ctor(this, name);
183     this->vtable = &MSVCP_bad_alloc_vtable;
184     return this;
185 }
186
187 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_copy_ctor, 8)
188 bad_alloc* __thiscall MSVCP_bad_alloc_copy_ctor(bad_alloc *this, const bad_alloc *rhs)
189 {
190     TRACE("%p %p\n", this, rhs);
191     MSVCP_exception_copy_ctor(this, rhs);
192     this->vtable = &MSVCP_bad_alloc_vtable;
193     return this;
194 }
195
196 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_dtor, 4)
197 void __thiscall MSVCP_bad_alloc_dtor(bad_alloc *this)
198 {
199     TRACE("%p\n", this);
200     MSVCP_exception_dtor(this);
201 }
202
203 DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_vector_dtor, 8)
204 void * __thiscall MSVCP_bad_alloc_vector_dtor(bad_alloc *this, unsigned int flags)
205 {
206     TRACE("%p %x\n", this, flags);
207     if(flags & 2) {
208         /* we have an array, with the number of elements stored before the first object */
209         int i, *ptr = (int *)this-1;
210
211         for(i=*ptr-1; i>=0; i--)
212             MSVCP_bad_alloc_dtor(this+i);
213         MSVCRT_operator_delete(ptr);
214     } else {
215         MSVCP_bad_alloc_dtor(this);
216         if(flags & 1)
217             MSVCRT_operator_delete(this);
218     }
219
220     return this;
221 }
222
223 DEFINE_THISCALL_WRAPPER(MSVCP_what_exception,4)
224 const char* __thiscall MSVCP_what_exception(exception * this)
225 {
226     TRACE("(%p) returning %s\n", this, this->name);
227     return this->name ? this->name : "Unknown exception";
228 }
229
230 static const type_info bad_alloc_type_info = {
231     &MSVCP_bad_alloc_vtable,
232     NULL,
233     ".?AVbad_alloc@std@@"
234 };
235
236 static const rtti_base_descriptor bad_alloc_rtti_base_descriptor = {
237     &bad_alloc_type_info,
238     1,
239     { 0, -1, 0 },
240     64
241 };
242
243 static const rtti_base_array bad_alloc_rtti_base_array = {
244     {
245         &bad_alloc_rtti_base_descriptor,
246         &exception_rtti_base_descriptor,
247         NULL
248     }
249 };
250
251 static const rtti_object_hierarchy bad_alloc_type_hierarchy = {
252     0,
253     0,
254     2,
255     &bad_alloc_rtti_base_array
256 };
257
258 const rtti_object_locator bad_alloc_rtti = {
259     0,
260     0,
261     0,
262     &bad_alloc_type_info,
263     &bad_alloc_type_hierarchy
264 };
265
266 static const cxx_type_info bad_alloc_cxx_type_info = {
267     0,
268     &bad_alloc_type_info,
269     { 0, -1, 0 },
270     sizeof(bad_alloc),
271     (cxx_copy_ctor)THISCALL(MSVCP_bad_alloc_copy_ctor)
272 };
273
274 static const cxx_type_info_table bad_alloc_cxx_type_table = {
275     2,
276     {
277         &bad_alloc_cxx_type_info,
278         &exception_cxx_type_info,
279         NULL
280     }
281 };
282
283 static const cxx_exception_type bad_alloc_cxx_type = {
284     0,
285     (cxx_copy_ctor)THISCALL(MSVCP_bad_alloc_dtor),
286     NULL,
287     &bad_alloc_cxx_type_table
288 };
289
290 /* logic_error class data */
291 typedef struct _logic_error {
292     exception e;
293     basic_string_char str;
294 } logic_error;
295
296 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_ctor, 8)
297 logic_error* __thiscall MSVCP_logic_error_ctor(
298         logic_error *this, const char **name)
299 {
300     TRACE("%p %s\n", this, *name);
301     this->e.vtable = &MSVCP_logic_error_vtable;
302     this->e.name = NULL;
303     this->e.do_free = FALSE;
304     MSVCP_basic_string_char_ctor_cstr(&this->str, *name);
305     return this;
306 }
307
308 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_copy_ctor, 8)
309 logic_error* __thiscall MSVCP_logic_error_copy_ctor(
310         logic_error *this, logic_error *rhs)
311 {
312     TRACE("%p %p\n", this, rhs);
313     MSVCP_exception_copy_ctor(&this->e, &rhs->e);
314     MSVCP_basic_string_char_copy_ctor(&this->str, &rhs->str);
315     this->e.vtable = &MSVCP_logic_error_vtable;
316     return this;
317 }
318
319 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_dtor, 4)
320 void __thiscall MSVCP_logic_error_dtor(logic_error *this)
321 {
322     TRACE("%p\n", this);
323     MSVCP_exception_dtor(&this->e);
324     MSVCP_basic_string_char_dtor(&this->str);
325 }
326
327 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_vector_dtor, 8)
328 void* __thiscall MSVCP_logic_error_vector_dtor(
329         logic_error *this, unsigned int flags)
330 {
331     TRACE("%p %x\n", this, flags);
332     if(flags & 2) {
333         /* we have an array, with the number of elements stored before the first object */
334         int i, *ptr = (int *)this-1;
335
336         for(i=*ptr-1; i>=0; i--)
337             MSVCP_logic_error_dtor(this+i);
338         MSVCRT_operator_delete(ptr);
339     } else {
340         MSVCP_logic_error_dtor(this);
341         if(flags & 1)
342             MSVCRT_operator_delete(this);
343     }
344
345     return this;
346 }
347
348 DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_what, 4)
349 const char* __thiscall MSVCP_logic_error_what(logic_error *this)
350 {
351     TRACE("%p\n", this);
352     return MSVCP_basic_string_char_c_str(&this->str);
353 }
354
355 static const type_info logic_error_type_info = {
356     &MSVCP_logic_error_vtable,
357     NULL,
358     ".?AVlogic_error@std@@"
359 };
360
361 static const rtti_base_descriptor logic_error_rtti_base_descriptor = {
362     &logic_error_type_info,
363     1,
364     { 0, -1, 0 },
365     64
366 };
367
368 static const rtti_base_array logic_error_rtti_base_array = {
369     {
370         &logic_error_rtti_base_descriptor,
371         &exception_rtti_base_descriptor,
372         NULL
373     }
374 };
375
376 static const rtti_object_hierarchy logic_error_type_hierarchy = {
377     0,
378     0,
379     2,
380     &logic_error_rtti_base_array
381 };
382
383 const rtti_object_locator logic_error_rtti = {
384     0,
385     0,
386     0,
387     &logic_error_type_info,
388     &logic_error_type_hierarchy
389 };
390
391 static const cxx_type_info logic_error_cxx_type_info = {
392     0,
393     &logic_error_type_info,
394     { 0, -1, 0 },
395     sizeof(logic_error),
396     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_copy_ctor)
397 };
398
399 static const cxx_type_info_table logic_error_cxx_type_table = {
400     2,
401     {
402         &logic_error_cxx_type_info,
403         &exception_cxx_type_info,
404         NULL
405     }
406 };
407
408 static const cxx_exception_type logic_error_cxx_type = {
409     0,
410     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_dtor),
411     NULL,
412     &logic_error_cxx_type_table
413 };
414
415 /* length_error class data */
416 typedef logic_error length_error;
417
418 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_ctor, 8)
419 length_error* __thiscall MSVCP_length_error_ctor(
420         length_error *this, const char **name)
421 {
422     TRACE("%p %s\n", this, *name);
423     MSVCP_logic_error_ctor(this, name);
424     this->e.vtable = &MSVCP_length_error_vtable;
425     return this;
426 }
427
428 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_copy_ctor, 8)
429 length_error* __thiscall MSVCP_length_error_copy_ctor(
430         length_error *this, length_error *rhs)
431 {
432     TRACE("%p %p\n", this, rhs);
433     MSVCP_logic_error_copy_ctor(this, rhs);
434     this->e.vtable = &MSVCP_length_error_vtable;
435     return this;
436 }
437
438 DEFINE_THISCALL_WRAPPER(MSVCP_length_error_vector_dtor, 8)
439 void* __thiscall MSVCP_length_error_vector_dtor(
440         length_error *this, unsigned int flags)
441 {
442     TRACE("%p %x\n", this, flags);
443     return MSVCP_logic_error_vector_dtor(this, flags);
444 }
445
446 static const type_info length_error_type_info = {
447     &MSVCP_length_error_vtable,
448     NULL,
449     ".?AVlength_error@std@@"
450 };
451
452 static const rtti_base_descriptor length_error_rtti_base_descriptor = {
453     &length_error_type_info,
454     2,
455     { 0, -1, 0 },
456     64
457 };
458
459 static const rtti_base_array length_error_rtti_base_array = {
460     {
461         &length_error_rtti_base_descriptor,
462         &logic_error_rtti_base_descriptor,
463         &exception_rtti_base_descriptor
464     }
465 };
466
467 static const rtti_object_hierarchy length_error_type_hierarchy = {
468     0,
469     0,
470     3,
471     &length_error_rtti_base_array
472 };
473
474 const rtti_object_locator length_error_rtti = {
475     0,
476     0,
477     0,
478     &length_error_type_info,
479     &length_error_type_hierarchy
480 };
481
482 static const cxx_type_info length_error_cxx_type_info = {
483     0,
484     &length_error_type_info,
485     { 0, -1, 0 },
486     sizeof(length_error),
487     (cxx_copy_ctor)THISCALL(MSVCP_length_error_copy_ctor)
488 };
489
490 static const cxx_type_info_table length_error_cxx_type_table = {
491     3,
492     {
493         &length_error_cxx_type_info,
494         &logic_error_cxx_type_info,
495         &exception_cxx_type_info
496     }
497 };
498
499 static const cxx_exception_type length_error_cxx_type = {
500     0,
501     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_dtor),
502     NULL,
503     &length_error_cxx_type_table
504 };
505
506 /* out_of_range class data */
507 typedef logic_error out_of_range;
508
509 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_ctor, 8)
510 out_of_range* __thiscall MSVCP_out_of_range_ctor(
511         out_of_range *this, const char **name)
512 {
513     TRACE("%p %s\n", this, *name);
514     MSVCP_logic_error_ctor(this, name);
515     this->e.vtable = &MSVCP_out_of_range_vtable;
516     return this;
517 }
518
519 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_copy_ctor, 8)
520 out_of_range* __thiscall MSVCP_out_of_range_copy_ctor(
521         out_of_range *this, out_of_range *rhs)
522 {
523     TRACE("%p %p\n", this, rhs);
524     MSVCP_logic_error_copy_ctor(this, rhs);
525     this->e.vtable = &MSVCP_out_of_range_vtable;
526     return this;
527 }
528
529 DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_vector_dtor, 8)
530 void* __thiscall MSVCP_out_of_range_vector_dtor(
531         out_of_range *this, unsigned int flags)
532 {
533     TRACE("%p %x\n", this, flags);
534     return MSVCP_logic_error_vector_dtor(this, flags);
535 }
536
537 static const type_info out_of_range_type_info = {
538     &MSVCP_out_of_range_vtable,
539     NULL,
540     ".?AVout_of_range@std@@"
541 };
542
543 static const rtti_base_descriptor out_of_range_rtti_base_descriptor = {
544     &out_of_range_type_info,
545     2,
546     { 0, -1, 0 },
547     64
548 };
549
550 static const rtti_base_array out_of_range_rtti_base_array = {
551     {
552         &out_of_range_rtti_base_descriptor,
553         &logic_error_rtti_base_descriptor,
554         &exception_rtti_base_descriptor
555     }
556 };
557
558 static const rtti_object_hierarchy out_of_range_type_hierarchy = {
559     0,
560     0,
561     3,
562     &out_of_range_rtti_base_array
563 };
564
565 const rtti_object_locator out_of_range_rtti = {
566     0,
567     0,
568     0,
569     &out_of_range_type_info,
570     &out_of_range_type_hierarchy
571 };
572
573 static const cxx_type_info out_of_range_cxx_type_info = {
574     0,
575     &out_of_range_type_info,
576     { 0, -1, 0 },
577     sizeof(out_of_range),
578     (cxx_copy_ctor)THISCALL(MSVCP_out_of_range_copy_ctor)
579 };
580
581 static const cxx_type_info_table out_of_range_cxx_type_table = {
582     3,
583     {
584         &out_of_range_cxx_type_info,
585         &logic_error_cxx_type_info,
586         &exception_cxx_type_info
587     }
588 };
589
590 static const cxx_exception_type out_of_range_cxx_type = {
591     0,
592     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_dtor),
593     NULL,
594     &out_of_range_cxx_type_table
595 };
596
597 /* invalid_argument class data */
598 typedef logic_error invalid_argument;
599
600 DEFINE_THISCALL_WRAPPER(MSVCP_invalid_argument_ctor, 8)
601 invalid_argument* __thiscall MSVCP_invalid_argument_ctor(
602         invalid_argument *this, const char **name)
603 {
604     TRACE("%p %s\n", this, *name);
605     MSVCP_logic_error_ctor(this, name);
606     this->e.vtable = &MSVCP_invalid_argument_vtable;
607     return this;
608 }
609
610 DEFINE_THISCALL_WRAPPER(MSVCP_invalid_argument_copy_ctor, 8)
611 invalid_argument* __thiscall MSVCP_invalid_argument_copy_ctor(
612         invalid_argument *this, invalid_argument *rhs)
613 {
614     TRACE("%p %p\n", this, rhs);
615     MSVCP_logic_error_copy_ctor(this, rhs);
616     this->e.vtable = &MSVCP_invalid_argument_vtable;
617     return this;
618 }
619
620 DEFINE_THISCALL_WRAPPER(MSVCP_invalid_argument_vector_dtor, 8)
621 void* __thiscall MSVCP_invalid_argument_vector_dtor(
622         invalid_argument *this, unsigned int flags)
623 {
624     TRACE("%p %x\n", this, flags);
625     return MSVCP_logic_error_vector_dtor(this, flags);
626 }
627
628 static const type_info invalid_argument_type_info = {
629     &MSVCP_invalid_argument_vtable,
630     NULL,
631     ".?AVinvalid_argument@std@@"
632 };
633
634 static const rtti_base_descriptor invalid_argument_rtti_base_descriptor = {
635     &invalid_argument_type_info,
636     2,
637     { 0, -1, 0 },
638     64
639 };
640
641 static const rtti_base_array invalid_argument_rtti_base_array = {
642     {
643         &invalid_argument_rtti_base_descriptor,
644         &logic_error_rtti_base_descriptor,
645         &exception_rtti_base_descriptor
646     }
647 };
648
649 static const rtti_object_hierarchy invalid_argument_type_hierarchy = {
650     0,
651     0,
652     3,
653     &invalid_argument_rtti_base_array
654 };
655
656 const rtti_object_locator invalid_argument_rtti = {
657     0,
658     0,
659     0,
660     &invalid_argument_type_info,
661     &invalid_argument_type_hierarchy
662 };
663
664 static const cxx_type_info invalid_argument_cxx_type_info = {
665     0,
666     &invalid_argument_type_info,
667     { 0, -1, 0 },
668     sizeof(invalid_argument),
669     (cxx_copy_ctor)THISCALL(MSVCP_invalid_argument_copy_ctor)
670 };
671
672 static const cxx_type_info_table invalid_argument_cxx_type_table = {
673     3,
674     {
675         &invalid_argument_cxx_type_info,
676         &logic_error_cxx_type_info,
677         &exception_cxx_type_info
678     }
679 };
680
681 static const cxx_exception_type invalid_argument_cxx_type = {
682     0,
683     (cxx_copy_ctor)THISCALL(MSVCP_logic_error_dtor),
684     NULL,
685     &invalid_argument_cxx_type_table
686 };
687
688 #ifndef __GNUC__
689 void __asm_dummy_vtables(void) {
690 #endif
691     __ASM_EXCEPTION_VTABLE(bad_alloc)
692     __ASM_EXCEPTION_STRING_VTABLE(logic_error)
693     __ASM_EXCEPTION_STRING_VTABLE(length_error)
694     __ASM_EXCEPTION_STRING_VTABLE(out_of_range)
695     __ASM_EXCEPTION_STRING_VTABLE(invalid_argument)
696 #ifndef __GNUC__
697 }
698 #endif
699
700 /* Internal: throws selected exception */
701 void throw_exception(exception_type et, const char *str)
702 {
703     const char *addr = str;
704
705     switch(et) {
706     case EXCEPTION: {
707         exception e;
708         MSVCP_exception_ctor(&e, &addr);
709         _CxxThrowException(&e, &exception_cxx_type);
710         return;
711     }
712     case EXCEPTION_BAD_ALLOC: {
713         bad_alloc e;
714         MSVCP_bad_alloc_ctor(&e, &addr);
715         _CxxThrowException(&e, &bad_alloc_cxx_type);
716         return;
717     }
718     case EXCEPTION_LOGIC_ERROR: {
719         logic_error e;
720         MSVCP_logic_error_ctor(&e, &addr);
721         _CxxThrowException((exception*)&e, &logic_error_cxx_type);
722         return;
723     }
724     case EXCEPTION_LENGTH_ERROR: {
725         length_error e;
726         MSVCP_length_error_ctor(&e, &addr);
727         _CxxThrowException((exception*)&e, &length_error_cxx_type);
728         return;
729     }
730     case EXCEPTION_OUT_OF_RANGE: {
731         out_of_range e;
732         MSVCP_out_of_range_ctor(&e, &addr);
733         _CxxThrowException((exception*)&e, &out_of_range_cxx_type);
734     }
735     case EXCEPTION_INVALID_ARGUMENT: {
736         invalid_argument e;
737         MSVCP_invalid_argument_ctor(&e, &addr);
738         _CxxThrowException((exception*)&e, &invalid_argument_cxx_type);
739     }
740     }
741 }