Piotr Caban : msvcrt: Fixed get_this_pointer implementation.
Alexandre Julliard
julliard at winehq.org
Mon Dec 10 14:00:39 CST 2012
Module: wine
Branch: master
Commit: b9c71ffd42ee4021fea363661d65170994482c3a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b9c71ffd42ee4021fea363661d65170994482c3a
Author: Piotr Caban <piotr at codeweavers.com>
Date: Mon Dec 10 16:13:50 2012 +0100
msvcrt: Fixed get_this_pointer implementation.
---
dlls/msvcrt/cppexcept.h | 17 +++++++++--------
dlls/msvcrt/tests/cpp.c | 12 ++++++++++++
2 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/dlls/msvcrt/cppexcept.h b/dlls/msvcrt/cppexcept.h
index d9ed2fa..7947a17 100644
--- a/dlls/msvcrt/cppexcept.h
+++ b/dlls/msvcrt/cppexcept.h
@@ -133,20 +133,21 @@ static inline const char *dbgstr_type_info( const type_info *info )
/* compute the this pointer for a base class of a given type */
static inline void *get_this_pointer( const this_ptr_offsets *off, void *object )
{
- void *this_ptr;
- int *offset_ptr;
-
if (!object) return NULL;
- this_ptr = (char *)object + off->this_offset;
+
if (off->vbase_descr >= 0)
{
+ int *offset_ptr;
+
/* move this ptr to vbase descriptor */
- this_ptr = (char *)this_ptr + off->vbase_descr;
+ object = (char *)object + off->vbase_descr;
/* and fetch additional offset from vbase descriptor */
- offset_ptr = (int *)(*(char **)this_ptr + off->vbase_offset);
- this_ptr = (char *)this_ptr + *offset_ptr;
+ offset_ptr = (int *)(*(char **)object + off->vbase_offset);
+ object = (char *)object + *offset_ptr;
}
- return this_ptr;
+
+ object = (char *)object + off->this_offset;
+ return object;
}
#ifndef __x86_64__
diff --git a/dlls/msvcrt/tests/cpp.c b/dlls/msvcrt/tests/cpp.c
index 8baf9b6..88f8225 100644
--- a/dlls/msvcrt/tests/cpp.c
+++ b/dlls/msvcrt/tests/cpp.c
@@ -901,6 +901,12 @@ static void test_rtti(void)
{ {RTTI_REF(child_class_rtti, base_descriptor[0]), RTTI_REF(child_class_rtti, base_descriptor[1])} },
{0, 0, 2, RTTI_REF(child_class_rtti, base_array)},
{1, 0, 0, RTTI_REF(child_class_rtti, type_info[1]), RTTI_REF(child_class_rtti, object_hierarchy), RTTI_REF(child_class_rtti, object_locator)}
+ }, virtual_base_class_rtti = {
+ { {NULL, NULL, "simple_class"}, {NULL, NULL, "child_class"} },
+ { {RTTI_REF(virtual_base_class_rtti, type_info[1]), 0, {0x10, sizeof(void*), sizeof(int)}, 0}, {RTTI_REF(virtual_base_class_rtti, type_info[0]), 0, {8, -1, 0}, 0} },
+ { {RTTI_REF(virtual_base_class_rtti, base_descriptor[0]), RTTI_REF(virtual_base_class_rtti, base_descriptor[1])} },
+ {0, 0, 2, RTTI_REF(virtual_base_class_rtti, base_array)},
+ {1, 0, 0, RTTI_REF(virtual_base_class_rtti, type_info[1]), RTTI_REF(virtual_base_class_rtti, object_hierarchy), RTTI_REF(virtual_base_class_rtti, object_locator)}
};
static struct rtti_data simple_class_sig0_rtti, child_class_sig0_rtti;
@@ -912,6 +918,9 @@ static void test_rtti(void)
void *simple_class_sig0 = &simple_class_sig0_vtbl[1];
void *child_class_sig0_vtbl[2] = {&child_class_sig0_rtti.object_locator};
void *child_class_sig0 = &child_class_sig0_vtbl[1];
+ void *virtual_base_class_vtbl[2] = {&virtual_base_class_rtti.object_locator};
+ int virtual_base_class_vbtbl[2] = {0, 0x100};
+ void *virtual_base_class[2] = {&virtual_base_class_vtbl[1], virtual_base_class_vbtbl};
static const char* e_name = "name";
type_info *ti,*bti;
@@ -1026,6 +1035,9 @@ static void test_rtti(void)
casted = p__RTDynamicCast(&child_class, 0, &child_class_rtti.type_info[0], &child_class_rtti.type_info[1], 0);
ok(casted == (char*)&child_class+4, "failed cast to child class (%p %p)\n", casted, &child_class);
+
+ casted = p__RTDynamicCast(&virtual_base_class, 0, &virtual_base_class_rtti.type_info[0], &virtual_base_class_rtti.type_info[1], 0);
+ ok(casted == (char*)&virtual_base_class+0x110+sizeof(void*), "failed cast to child class (%p %p)\n", casted, &virtual_base_class);
}
struct _demangle {
More information about the wine-cvs
mailing list