[Bug target/12413] 'symbol already defined' when building ICU 2.6 with Cygwin

dannysmith at gcc dot gnu dot org gcc-bugzilla@gcc.gnu.org
Mon Jan 19 21:35:00 GMT 2004


------- Additional Comments From dannysmith at gcc dot gnu dot org  2004-01-19 21:35 -------
Hello.

This bug is caused by the way vtable are handled in cp/decl2.c
(import_export_vtable) vs the need for the dllimport marking mechanism
to avoid marking defined data as dllimport. The vtable may be first
marked as DECL_EXTERNAL when import_export_vtable is called by
maybe_emit_vtables() and then later (when final == 1), the DECL_EXTERNAL
is removed. This change in storage class causes the problems. When
config/i386/winnt.c (i386_pe_dllimport_p) sees the DECL_EXTERNAL on a
vtable symbol from a dllimported class, it tells
i386_pe_mark_dllimport() to decorate the symbol with _imp_ prefix, and
to pass it through get_identifier. When the DECL_EXTERNAL is later
removed by import_export_vtable, the vtable definition is emitted, but
with a bogus identifier.


Here is one way to fix:

Patch (1)

cp/ChangedLog

	decl2.c (import_export_vtable): Always set DECL_EXTERNAL for
	vtables of dllimported classes.


Index: decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.695
diff -c -3 -p -r1.695 decl2.c
*** decl2.c	13 Jan 2004 23:59:19 -0000	1.695
--- decl2.c	18 Jan 2004 02:45:21 -0000
*************** import_export_vtable (tree decl, tree ty
*** 1447,1453 ****
    if (DECL_INTERFACE_KNOWN (decl))
      return;
  
!   if (TYPE_FOR_JAVA (type))
      {
        TREE_PUBLIC (decl) = 1;
        DECL_EXTERNAL (decl) = 1;
--- 1447,1454 ----
    if (DECL_INTERFACE_KNOWN (decl))
      return;
  
!   if (TYPE_FOR_JAVA (type)
!       || lookup_attribute ("dllimport", TYPE_ATTRIBUTES (type)))
      {
        TREE_PUBLIC (decl) = 1;
        DECL_EXTERNAL (decl) = 1;


Following is another way to fix, that is more intrusive. but by removing
all the MULTIPLE_SYMBOL_SPACE business, we also get a fix for some problems
with #pragma interface when linking against static libs.

If we remove the MULTIPLE_SYMBOL_SPACES define for win32 targets. then
we set both INTERFACE_ONLY and INTERFACE_KNOWN for dllimported classes.
This is the right thing to do for vtables, since (1) vtables are always
exported from the dll along with the class as long as the class type
definition has the dllexport attribute (or if ld is told to
--export-all), and (2) vtables get marked as dllimport when the class is
imported. It is also the right thing to do for ordinary class members,
since dllimport means the that symbols are defined exterally. However,
it is not the right thing to do for type info nodes, since these do not
currently inherit the dll attributes of the class (should they?). So
rather than tarring the whole class with MULTIPLE_SYMBOL_SPACES
protection, we just make a special excption for type info objects, and
always emit them even if a class has INTERFACE_ONLY set by virtue of
dllimport attribute.

I suspect I'm missing something.  The problem is I don't really
understand the logic behind the MULTIPLE_SYMBOL_SPACES in the first
place.  Can someone more familiar with the history of this please
suggest a testcase that shows why it was/is needed.


Jason, since your name appears most often against MULTIPLE_SYMBOL_SPACES in 
ChangeLogs I've add you to CC.


Patch (2):


ChangeLog

	* config/i386/cygming.h (MULTIPLE_SYMBOL_SPACES): Don't define.

cp/ChangeLog

	* decl2.c (import_export_tinfo): Always emit tinfo nodes for
	dllimported classes.
 

Index: config/i386/cygming.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/cygming.h,v
retrieving revision 1.11
diff -c -3 -p -r1.11 cygming.h
*** config/i386/cygming.h	2 Jan 2004 15:30:42 -0000	1.11
--- config/i386/cygming.h	19 Jan 2004 21:06:23 -0000
*************** do {							\
*** 249,255 ****
     unit may not be bound to undefined symbols in another translation unit
     without user intervention.  For instance, under Microsoft Windows
     symbols must be explicitly imported from shared libraries (DLLs).  */
! #define MULTIPLE_SYMBOL_SPACES
  
  extern void i386_pe_unique_section (TREE, int);
  #define TARGET_ASM_UNIQUE_SECTION i386_pe_unique_section
--- 249,255 ----
     unit may not be bound to undefined symbols in another translation unit
     without user intervention.  For instance, under Microsoft Windows
     symbols must be explicitly imported from shared libraries (DLLs).  */
! #undef MULTIPLE_SYMBOL_SPACES
  
  extern void i386_pe_unique_section (TREE, int);
  #define TARGET_ASM_UNIQUE_SECTION i386_pe_unique_section
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.695
diff -c -3 -p -r1.695 decl2.c
*** cp/decl2.c	13 Jan 2004 23:59:19 -0000	1.695
--- cp/decl2.c	19 Jan 2004 21:06:30 -0000
*************** import_export_tinfo (tree decl, tree typ
*** 1740,1746 ****
        /* If -fno-rtti, we're not necessarily emitting this stuff with
  	 the class, so go ahead and emit it now.  This can happen when
  	 a class is used in exception handling.  */
!       && flag_rtti)
      {
        DECL_NOT_REALLY_EXTERN (decl) = !CLASSTYPE_INTERFACE_ONLY (type);
        DECL_COMDAT (decl) = 0;
--- 1740,1754 ----
        /* If -fno-rtti, we're not necessarily emitting this stuff with
  	 the class, so go ahead and emit it now.  This can happen when
  	 a class is used in exception handling.  */
!       && flag_rtti
! #if defined (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
!       /* FIXME: Always emit typeinfo for dllimported classes, since we
! 	 don't know if it has been exported from the library. Even if it
! 	 has been exported, we would still need to add the dllimport
! 	 attribute to the typeinfo object to get it to link correctly.  */
!       && !lookup_attribute ("dllimport", TYPE_ATTRIBUTES (type))
! #endif
!      )
      {
        DECL_NOT_REALLY_EXTERN (decl) = !CLASSTYPE_INTERFACE_ONLY (type);
        DECL_COMDAT (decl) = 0;



Danny


-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at redhat dot com,
                   |                            |dannysmith at gcc dot gnu
                   |                            |dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12413



More information about the Gcc-bugs mailing list