The dllimport attribute on windows targets does not play nice with the heuristics used to emit vtables. Example: ========================================== // dllimport-vtable.C struct __attribute__((dllimport)) S { virtual void f(){}; }; S s; ========================================== using gcc version 3.5.0 20040901 (experimental) > g++ -S dllimport-vtable.C produces: .file "dllimport-vtable.C" .globl _s .bss .align 4 _s: .space 4 .globl _) .section .rdata$_ZTV1S,"dr" .linkonce same_size .align 8 _): <<<< bogus symbol ref for _ZTV1S .long 0 .long __ZTI1S .long __ZN1S1fEv < snip > .section .text$_ZN1SC1Ev,"x" .linkonce discard .align 2 .globl __ZN1SC1Ev .def __ZN1SC1Ev; .scl 2; .type 32; .endef __ZN1SC1Ev: LFB6: pushl %ebp LCFI2: movl %esp, %ebp LCFI3: movl 8(%ebp), %eax movl __imp___ZTV1S, %edx <<<< winnt.c changed the symbol ref addl $8, %edx movl %edx, (%eax) popl %ebp ret LFE6: The import status specified by dllimport is ignored because of the MULTIPLE_SYMBOL_SPACES override in cp/decl2.c:import_export_class. Consequently, import_export_decl marks the vtable as comdat. However, the decl also still has the DECL_EXTERNAL flag. When winnt.c:i386_pe_mark_dllimport sees the DECL_EXTERNAL it thinks it is okay to honour the dllimport attribute and so replaces the SYMBOL_REF_DECL with an encoded identifier. I don't think this is a new bug, it's just easier to reproduce now. I believe that http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12413 is caused by similar lossage of symbol ref I see two ways to fix. 1) Removing the MULTIPLE_SYMBOL_SPACES override in import_export_class works, With #pragma interface deprecated, some of the earlier reasons for this override are probably gone. However, it means that a new MULTIPLE_SYMBOL_SPACES guard (or similar) is needed in import_export_decl when handling tinfo decls. Marking tinfo decls as dllimport causes problems when a tinfo node needs to be put into a vtable or tinfo table of a derived class: Dllimported symbols have DECL_NON_ADDR_CONST_P set (can't treat a pointer to this as a constant address) since the data is obtained as *__imp___ZTI1S I'm currently testing a patch along these lines and will submit shortly 2) Change winnt.c so that it never imports vtables. I tried this once before and it led to frequent failures with unresolved vtable references in multiple inheritance case. So that solution, besides being inefficient, needs some work. Danny
Patch submitted: http://gcc.gnu.org/ml/gcc-patches/2004-09/msg00442.html Danny
Confirmed.
The example produces a correct label for the vtable (_ZTV1S) with 4.2.2 and trunk, so closing as fixed. However we still emit the definition of the vtable even though we import it from the dll as __imp___ZTV1S when constructing the object s. Danny