This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch] Fix dllimport regression from 2.95 on w32 targets
- From: Danny Smith <danny_r_smith_2001 at yahoo dot co dot nz>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: jason at redhat dot com, cgf at redhat dot com
- Date: Mon, 16 Sep 2002 09:56:44 +1000 (EST)
- Subject: [Patch] Fix dllimport regression from 2.95 on w32 targets
Hello
As used by native windows compiler, the dllimport attribute implicitly adds
'extern' to dllimported vars. This was also case with gcc-2.95 for windows
targets, but not with 3.x. This causes problems with uninitialised variables
and can best be seen in C++.
The following code compiled with 2.95:
================================================
/* extern_import.cpp */
struct Foo
{
int bar;
};
__attribute__ ((__dllimport__)) Foo export_Foo1;
__attribute__ ((__dllimport__)) Foo export_Foo2;
int baz()
{
return export_Foo1.bar + export_Foo2.bar;
}
=================================================
With 3.x, it fails with confusing assembler message.
D:\TEMP/ccddaaaa.s:11: Error: symbol `_N' is already defined
gcc -S extern_import.cpp produces:
.file "extern_import.cpp"
.globl _N
.globl _N
.bss
.align 4
_N:
.space 4
.globl _N
.globl _N
.align 4
_N:
.space 4
....
As pointed out to me by Jason Merrill:
>> This is a change from 2.95, a side-effect of waiting to set
>> DECL_RTL until it is actually needed. As a result, i386_pe_mark_dllimport
>> isn't called until after assemble_variable has checked DECL_EXTERNAL, so we
>> don't know that the variable is supposed to be extern.
The following patch, tested on i586-pc-mingw32 with 3.2.1 and 3.3, fixes
the regression.
The patch has been pre-approved by Christopher Faylor in private
correspondence.
Okay for trunk? 3.2.1?
ChangeLog
2002-09-16 Jason Merrill <jason@redhat.com>
Danny Smith <dannysmith@users.sourceforge.net>
* config/i386/winnt.c (ix86_handle_dll_attribute): Set
DECL_EXTERN and TREE_PUBLIC for dllimported variables here...
(i386_pe_mark_dllimport): Not here.
Index: winnt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/winnt.c,v
retrieving revision 1.34
diff -u -p -r1.34 winnt.c
--- winnt.c 4 Aug 2002 22:45:23 -0000 1.34
+++ winnt.c 15 Sep 2002 22:52:33 -0000
@@ -78,6 +78,15 @@ ix86_handle_dll_attribute (node, name, a
}
}
+ /* `extern' needn't be specified with dllimport.
+ Specify `extern' now and hope for the best. Sigh. */
+ else if (TREE_CODE (*node) == VAR_DECL
+ && is_attribute_p ("dllimport", name))
+ {
+ DECL_EXTERNAL (*node) = 1;
+ TREE_PUBLIC (*node) = 1;
+ }
+
return NULL_TREE;
}
@@ -300,16 +309,6 @@ i386_pe_mark_dllimport (decl)
{
error_with_decl (decl, "static variable `%s' is marked dllimport");
return;
- }
-
- /* `extern' needn't be specified with dllimport.
- Specify `extern' now and hope for the best. Sigh. */
- if (TREE_CODE (decl) == VAR_DECL
- /* ??? Is this test for vtables needed? */
- && !DECL_VIRTUAL_P (decl))
- {
- DECL_EXTERNAL (decl) = 1;
- TREE_PUBLIC (decl) = 1;
}
newname = alloca (strlen (oldname) + 11);
http://mobile.yahoo.com.au - Yahoo! Messenger for SMS
- Always be connected to your Messenger Friends