This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/17300] New: [mingw./cygwin]: dllimport of C++ classes with vtables cuases bogus symbol ref
- From: "dannysmith at users dot sourceforge dot net" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 2 Sep 2004 21:51:05 -0000
- Subject: [Bug target/17300] New: [mingw./cygwin]: dllimport of C++ classes with vtables cuases bogus symbol ref
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
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
--
Summary: [mingw./cygwin]: dllimport of C++ classes with vtables
cuases bogus symbol ref
Product: gcc
Version: 3.5.0
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: target
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: dannysmith at users dot sourceforge dot net
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: i686-pc-mingw32
GCC host triplet: i686-pc-mingw32
GCC target triplet: i686-pc-mingw32
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17300