Workaround for virtual function/dllimport bug, also patch guidance request
Mumit Khan
khan@NanoTech.Wisc.EDU
Fri Dec 31 23:54:00 GMT 1999
Jason Merrill <jason@cygnus.com> writes:
>
> > Because of the usual `can't take the address of imported symbol' crap.
>
> Does that apply to all non-functions? Why? How do we import vtables, then?
It was my mistake in looking at the symbol table instead of the assembler.
Following is an annotated example of what MSVC does.
> I'd prefer to spend the time to get it right.
So would I of course.
Quick summary: It does indeed look like MSVC is generating vtables and RTTI
for *all* imported classes, but it's hiding the vtables for imported classes
in something called ``local vftable''. It's essentially the same behavior
as the MULTIPLE_SYMBOL_SPACES case.
Take the following code:
struct __declspec(dllimport)
Base
{
Base ();
virtual ~Base ();
virtual void vf1 ();
};
struct
Derived : public Base
{
Derived () { }
virtual ~Derived () { }
virtual void vf1 ();
};
static void f1 (Base*);
void
Derived::vf1 () {
f1 (new Base);
f1 (new Derived);
}
static void
f1 (Base* b)
{
b->vf1 ();
delete b;
}
Now look at the symbols, especially the ones marked with '<<':
(fyi type 'R' is COMDAT)
00000000 T ??0Derived@@QAE@XZ
00000000 T ??1Derived@@UAE@XZ
U ??2@YAPAXI@Z
U ??3@YAXPAX@Z
00000004 R ??_7Derived@@6B@ << Derived::vtable
U ??_7type_info@@6B@ << type_info::vtable
U ??_EBase@@UAEPAXI@Z
U ??_EDerived@@UAEPAXI@Z
00000000 T ??_GBase@@UAEPAXI@Z
U ??_GBase@@UAEPAXI@Z
00000000 T ??_GDerived@@UAEPAXI@Z
U ??_GDerived@@UAEPAXI@Z
00000000 D ??_R0?AUBase@@@8 << Begin RTTI syms ...
00000000 D ??_R0?AUDerived@@@8
00000000 R ??_R1A@?0A@A@Base@@8
00000000 R ??_R1A@?0A@A@Derived@@8
00000000 R ??_R2Base@@8
00000000 R ??_R2Derived@@8
00000000 R ??_R3Base@@8
00000000 R ??_R3Derived@@8
00000000 R ??_R4Base@@6B@
00000000 R ??_R4Derived@@6B@ << ... end RTTI syms
00000004 R ??_SBase@@6B@ << Base::`local vtable'
00000080 t ?f1@@YAXPAUBase@@@Z
U ?vf1@Base@@UAEXXZ
00000000 T ?vf1@Derived@@UAEXXZ
000b1fe8 a @comp.id
U __imp_??0Base@@QAE@XZ
U __imp_??1Base@@UAE@XZ
Note how it does indeed emit vtable for imported class, Base, but under
a different name which I had missed before -- ??_SBase@@6B@. And it of
course emits RTTI for imported classes as well.
I'm attaching the .asm generated as well as the output of dumbin, which
is sometimes quite useful.
Wish I'd done this earlier.
With this, I believe the solution is the following:
1. Restore the older behavior in import_export_class, ie., the same as
MULTIPLE_SYMBOL_SPACES case, and don't import vtables and RTTI nodes
or functions.
2. Fix the remaining issue with check_for_override in tsubst_decl. I'll
get an updated patch out today.
Regards,
Mumit
More information about the Gcc
mailing list