Bug 37121 - g++ create global symbol for inline function, which make link failed with multiple definitions
Summary: g++ create global symbol for inline function, which make link failed with mul...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.4.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-08-14 07:03 UTC by drangon
Modified: 2009-08-18 11:03 UTC (History)
4 users (show)

See Also:
Host: x86_64-pc-mingw32
Target: x86_64-pc-mingw32
Build: x86_64-redhat-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments
output of gcc -E (288.29 KB, application/gzip)
2008-09-25 04:45 UTC, drangon
Details
output of nm, the object is build by gcc -O0 (3.01 KB, text/plain)
2008-09-25 04:47 UTC, drangon
Details
output of nm, the object is build by gcc -O1 (2.34 KB, text/plain)
2008-09-25 04:48 UTC, drangon
Details
output of objdump, the object is build by gcc -O0 (364.69 KB, application/gzip)
2008-09-25 04:48 UTC, drangon
Details
output of objdump, the object is build by gcc -O1 (374.99 KB, application/gzip)
2008-09-25 04:49 UTC, drangon
Details
gcc -E output ( gcc 4.4.0 svn 20090307 ) (289.18 KB, application/x-zip-compressed)
2009-03-07 15:02 UTC, drangon
Details
the output object of thread.o (57.44 KB, application/octet-stream)
2009-03-07 15:10 UTC, drangon
Details

Note You need to log in before you can comment on or make changes to this bug.
Description drangon 2008-08-14 07:03:29 UTC
when use g++ to build wxWidgets in x86_64-pc-mingw32, it output following error :

------------------
E:\work\09_workroom\wxtest\png>mingw32-make -f Makefile.mingw WX_DIR=e:\code\wx6
4 CXX=e:\code\target\bin\g++.exe
e:\code\target\bin\g++.exe -g -Wall -pipe  -D__WXMSW__ -D__WXDEBUG__ -DWIN32 -D_
WINDOWS -Ie:\code\wx64/include -Ie:\code\wx64/lib/mswd  png.o  stdafx.o -o png.e
xe -mwindows -Le:\code\wx64/lib -lwxmsw28d_core -lwxbase28d -lwxpngd -lwxzlibd -
lgdi32 -lole32 -loleaut32 -lwinmm -lcomctl32 -lcomdlg32 -lwinspool -luuid -lshel
l32 -lrpcrt4
e:/code/target/bin/../lib/gcc/x86_64-pc-mingw32/4.3.2/../../../../x86_64-pc-ming
w32/lib/libmingwex.a(lib64_libmingwex_a-wininterlocked.o):wininterlocked.c:(.tex
t+0x43b): multiple definition of `_InterlockedIncrement'
e:\code\wx64/lib/libwxbase28d.a(baselib_thread.o):thread.cpp:(.text$_Interlocked
Increment[__InterlockedIncrement]+0x0): first defined here
e:/code/target/bin/../lib/gcc/x86_64-pc-mingw32/4.3.2/../../../../x86_64-pc-ming
w32/lib/libmingwex.a(lib64_libmingwex_a-wininterlocked.o):wininterlocked.c:(.tex
t+0x487): multiple definition of `_InterlockedDecrement'
e:\code\wx64/lib/libwxbase28d.a(baselib_thread.o):thread.cpp:(.text$_Interlocked
Decrement[__InterlockedDecrement]+0x0): first defined here
collect2: ld returned 1 exit status
mingw32-make: *** [png.exe] Error 1	
-----------------

_InterlockedDecrement is an inline function, it should not in baselib_thread.o,
when built with "-O1", its ok. when built with "-O2", g++ crashed.
see attachment for more infomation.
Comment 1 drangon 2008-09-25 04:45:31 UTC
Created attachment 16405 [details]
output of gcc -E
Comment 2 drangon 2008-09-25 04:47:14 UTC
Created attachment 16406 [details]
output of nm, the object is build by gcc -O0
Comment 3 drangon 2008-09-25 04:48:01 UTC
Created attachment 16407 [details]
output of nm, the object is build by gcc -O1
Comment 4 drangon 2008-09-25 04:48:52 UTC
Created attachment 16408 [details]
output of objdump, the object is build by gcc -O0
Comment 5 drangon 2008-09-25 04:49:25 UTC
Created attachment 16409 [details]
output of objdump, the object is build by gcc -O1
Comment 6 nightstrike 2008-09-25 05:00:20 UTC
What is the output of g++ -v?

Are you using the win32 cross compiler, or the win64 native compiler?
Comment 7 drangon 2008-09-26 00:33:04 UTC
I'm using the win64 native compiler:

E:\code>g++ -v
Using built-in specs.
Target: x86_64-pc-mingw32
Configured with: ../gcc/configure --host=x86_64-pc-mingw32 --target=x86_64-pc-mi
ngw32 --disable-nls --enable-languages=c,c++ --with-gmp=/home/drangon/mingw/for_
target --enable-twoprocess --prefix=/home/drangon/mingw/target --with-sysroot=/h
ome/drangon/mingw/target
Thread model: win32
gcc version 4.4.0 20080814 (experimental) (GCC)
Comment 8 Kai Tietz 2009-02-28 17:48:11 UTC
I can't test your precompiled code, because c++ has changed in an incompatible way. Could you attach a current precompiled version using gcc4.4 of it?
Is the problem still present on 4.4.0 ?
Comment 9 drangon 2009-03-07 14:52:23 UTC
(In reply to comment #8)
> I can't test your precompiled code, because c++ has changed in an incompatible
> way. Could you attach a current precompiled version using gcc4.4 of it?
> Is the problem still present on 4.4.0 ?
> 

I built the native toolchain using the newest source code, the problem still present.

Comment 10 drangon 2009-03-07 15:02:10 UTC
Created attachment 17413 [details]
gcc -E output ( gcc 4.4.0 svn 20090307 )
Comment 11 drangon 2009-03-07 15:10:28 UTC
Created attachment 17414 [details]
the output object of thread.o
Comment 12 nightstrike 2009-03-09 02:10:43 UTC
Was this broken in 4.3 compilers?  Is it a 4.4 regression?
Comment 13 Danny Smith 2009-03-09 07:46:01 UTC
(In reply to comment #12)
> Was this broken in 4.3 compilers?  Is it a 4.4 regression?
> 
This is not a new bug in the compiler (the same multiple definition will occur with 3.4.5)  , but an old 'feature' of the the PE-COFF linker

_InterlockedIncrement is defined as an ordinary  C library function  in lib64_libmingwex_a-wininterlocked.o

In thread.cpp, it is defined and emitted using linkonce semantics (it is put into its own .text$_InterlockedIncrement link_once sections, which is how PE-COFF implements vague linkage.

The linker grabs the one and only .text$_InterlockedIncrement section in thread.o and then while resolving another symbol it needs from lib64_libmingwex_a-wininterlocked.o finds an ordinary (not .linkonce) definition InterlockedIncrement

Hence the multiple definition.


Comment 14 drangon 2009-04-21 05:35:24 UTC
how to fix this multiple definition issue ?

adjust the linker to allow this ?

or remove the ordinary  C library function in lib64_libmingwex_a-wininterlocked.o and just keep the inline function ?

or remove the inline function, replace by a function declaration which use the implementation from lib64_libmingwex_a-wininterlocked.o ?
Comment 15 Danny Smith 2009-04-21 07:01:35 UTC
(In reply to comment #14)

> or remove the ordinary  C library function in
> lib64_libmingwex_a-wininterlocked.o and just keep the inline function ?
> 

That would be my first experiment.  What depends on  lib64_libmingwex_a-wininterlocked.o 
Danny
Comment 16 Kai Tietz 2009-04-21 08:27:38 UTC
(In reply to comment #15)
> (In reply to comment #14)
> > or remove the ordinary  C library function in
> > lib64_libmingwex_a-wininterlocked.o and just keep the inline function ?
> > 
> That would be my first experiment.  What depends on 
> lib64_libmingwex_a-wininterlocked.o 
> Danny

we implemented int wininterlocked.c file the common interlocked symbols, because some of them should be inlined for performance reasons. To remove the inline version seems to be the best solution for me here. Because otherwise we would disallow a function pointer reference to it.
Possibly we could make als define those symbols in wininterlocked.c as weak, does this help?

Kai
Comment 17 Kai Tietz 2009-04-21 08:49:57 UTC
Ah, C++ makes here the trouble. We found the same issue about math.h. Here I fixed it by avoiding to define the inline functions for C++.
I assumed it was fixed already, but this doesn't seem so. It seems that in C++ the meaning of inline functions in extern "C" blocks has altered by intention, or this regression still exists.

Kai
Comment 18 Kai Tietz 2009-08-18 11:03:02 UTC
This bug is fixed by a recent change to our runtime headers. We support now the NO_INLINE feature for platform headers, too. So, even intrinsic functions aren't emitted anymore, when __NO_INLINE__ is defined.