diff --git a/dlls/msvcp90/exception.c b/dlls/msvcp90/exception.c index d795b660fc..b4c8bff55b 100644 --- a/dlls/msvcp90/exception.c +++ b/dlls/msvcp90/exception.c @@ -101,6 +101,7 @@ void CDECL _CxxThrowException(exception*,const cxx_exception_type*); extern const vtable_ptr MSVCP_bad_alloc_vtable; extern const vtable_ptr MSVCP_logic_error_vtable; extern const vtable_ptr MSVCP_length_error_vtable; +extern const vtable_ptr MSVCP_out_of_range_vtable; /* exception class data */ static type_info exception_type_info = { @@ -519,12 +520,104 @@ static const cxx_exception_type length_error_cxx_type = { &length_error_cxx_type_table }; +/* out_of_range class data */ +typedef logic_error out_of_range; + +DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_ctor, 8) +out_of_range* __stdcall MSVCP_out_of_range_ctor( + out_of_range *this, const char **name) +{ + TRACE("%p %s\n", this, *name); + MSVCP_logic_error_ctor(this, name); + this->e.vtable = &MSVCP_out_of_range_vtable; + return this; +} + +DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_copy_ctor, 8) +out_of_range* __stdcall MSVCP_out_of_range_copy_ctor( + out_of_range *this, out_of_range *rhs) +{ + TRACE("%p %p\n", this, rhs); + MSVCP_logic_error_copy_ctor(this, rhs); + this->e.vtable = &MSVCP_out_of_range_vtable; + return this; +} + +DEFINE_THISCALL_WRAPPER(MSVCP_out_of_range_vector_dtor, 8) +void* __stdcall MSVCP_out_of_range_vector_dtor( + out_of_range *this, unsigned int flags) +{ + TRACE("%p %x\n", this, flags); + return MSVCP_logic_error_vector_dtor(this, flags); +} + +static const type_info out_of_range_type_info = { + &MSVCP_out_of_range_vtable, + NULL, + ".?AVout_of_range@std@@" +}; + +static const rtti_base_descriptor out_of_range_rtti_base_descriptor = { + &out_of_range_type_info, + 2, + { 0, -1, 0 }, + 64 +}; + +static const rtti_base_array out_of_range_rtti_base_array = { + { + &out_of_range_rtti_base_descriptor, + &logic_error_rtti_base_descriptor, + &exception_rtti_base_descriptor + } +}; + +static const rtti_object_hierarchy out_of_range_type_hierarchy = { + 0, + 0, + 3, + &out_of_range_rtti_base_array +}; + +const rtti_object_locator out_of_range_rtti = { + 0, + 0, + 0, + &out_of_range_type_info, + &out_of_range_type_hierarchy +}; + +static const cxx_type_info out_of_range_cxx_type_info = { + 0, + &out_of_range_type_info, + { 0, -1, 0 }, + sizeof(out_of_range), + (cxx_copy_ctor)THISCALL(MSVCP_out_of_range_copy_ctor) +}; + +static const cxx_type_info_table out_of_range_cxx_type_table = { + 3, + { + &out_of_range_cxx_type_info, + &logic_error_cxx_type_info, + &exception_cxx_type_info + } +}; + +static const cxx_exception_type out_of_range_cxx_type = { + 0, + (cxx_copy_ctor)THISCALL(MSVCP_logic_error_dtor), + NULL, + &out_of_range_cxx_type_table +}; + #ifndef __GNUC__ void __asm_dummy_vtables(void) { #endif __ASM_EXCEPTION_VTABLE(bad_alloc) __ASM_EXCEPTION_STRING_VTABLE(logic_error) __ASM_EXCEPTION_STRING_VTABLE(length_error) + __ASM_EXCEPTION_STRING_VTABLE(out_of_range) #ifndef __GNUC__ } #endif @@ -559,5 +652,10 @@ void throw_exception(exception_type et, const char *str) _CxxThrowException((exception*)&e, &length_error_cxx_type); return; } + case EXCEPTION_OUT_OF_RANGE: { + out_of_range e; + MSVCP_out_of_range_ctor(&e, &addr); + _CxxThrowException((exception*)&e, &out_of_range_cxx_type); + } } } diff --git a/dlls/msvcp90/msvcp90.h b/dlls/msvcp90/msvcp90.h index 3c43117543..bc3c73d954 100644 --- a/dlls/msvcp90/msvcp90.h +++ b/dlls/msvcp90/msvcp90.h @@ -61,7 +61,8 @@ typedef enum __exception_type { EXCEPTION, EXCEPTION_BAD_ALLOC, EXCEPTION_LOGIC_ERROR, - EXCEPTION_LENGTH_ERROR + EXCEPTION_LENGTH_ERROR, + EXCEPTION_OUT_OF_RANGE } exception_type; void throw_exception(exception_type, const char *); void set_exception_vtable(void); diff --git a/dlls/msvcp90/msvcp90.spec b/dlls/msvcp90/msvcp90.spec index 4a442c6684..898cac5c43 100644 --- a/dlls/msvcp90/msvcp90.spec +++ b/dlls/msvcp90/msvcp90.spec @@ -2881,7 +2881,7 @@ @ cdecl ?_Xlen@_String_base@std@@SAXXZ() MSVCP__String_base_Xlen @ stub ?_Xmem@tr1@std@@YAXXZ @ stub ?_Xoutrange@tr1@std@@YAXXZ -@ stub ?_Xran@_String_base@std@@SAXXZ +@ cdecl ?_Xran@_String_base@std@@SAXXZ() MSVCP__String_base_Xran @ stub ?_Xran@ctype_base@std@@KAXXZ @ stub -arch=win32 ?_Xsgetn_s@?$basic_streambuf@DU?$char_traits@D@std@@@std@@MAEHPADIH@Z @ stub -arch=win64 ?_Xsgetn_s@?$basic_streambuf@DU?$char_traits@D@std@@@std@@MEAA_JPEAD_K_J@Z diff --git a/dlls/msvcp90/string.c b/dlls/msvcp90/string.c index 3b8fc66f39..97c47d046e 100644 --- a/dlls/msvcp90/string.c +++ b/dlls/msvcp90/string.c @@ -476,6 +476,15 @@ void CDECL MSVCP__String_base_Xlen(void) throw_exception(EXCEPTION_LENGTH_ERROR, msg); } +/* ?_Xran@_String_base@std@@SAXXZ */ +void CDECL MSVCP__String_base_Xran(void) +{ + static const char msg[] = "invalid string position"; + + TRACE("\n"); + throw_exception(EXCEPTION_OUT_OF_RANGE, msg); +} + /* basic_string, allocator> */ /* ?npos@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@2IB */ @@ -580,7 +589,7 @@ basic_string_char* __stdcall MSVCP_basic_string_char_erase( TRACE("%p %d %d\n", this, pos, len); if(pos > this->size) { - FIXME("Throw exception (_Xran)\n"); + MSVCP__String_base_Xran(); return NULL; } @@ -607,7 +616,7 @@ basic_string_char* __stdcall MSVCP_basic_string_char_assign_substr( TRACE("%p %p %d %d\n", this, assign, pos, len); if(assign->size < pos) { - FIXME("Throw exception (_Xran)\n"); + MSVCP__String_base_Xran(); return NULL; }