This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/17300] New: [mingw./cygwin]: dllimport of C++ classes with vtables cuases bogus symbol ref


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]