$ cat > bug.cc << EOF > struct cl_heap { > int refcount; > }; > > class cl_gcpointer { > public: > cl_heap* heappointer; > cl_gcpointer (const char * s); > ~cl_gcpointer () > { > if (--heappointer->refcount == 0) > delete heappointer; > } > }; > > struct cl_symbol { > public: > cl_symbol (const cl_gcpointer&); > }; > > cl_symbol cl_univpoly_varname_key = (cl_symbol)"variable name"; > > struct cl_module_destroyer { > inline cl_module_destroyer () > { > __asm__("\nthis_symbol_is_defined_once_or_twice:"); > } > }; > EOF $ g++ -O -c fatal.cc $ g++ -O2 -c fatal.cc /tmp/ccDX2LCa.s: Assembler messages: /tmp/ccDX2LCa.s:152: Error: symbol `this_symbol_is_defined_once_or_twice' is already defined This does not happen on a ia32 platform. The bug above was distilled from CLN. It is responsible for the package failing to build on Debian/sid <http://buildd.debian.org/fetch.php?&pkg=cln&ver=1.1.9-4&arch=ia64&stamp=1123630039&file=log&as=raw>. It appears to happen on m68k, too: <http://buildd.debian.org/fetch.php?&pkg=cln&ver=1.1.9-4&arch=m68k&stamp=1123757682&file=log&as=raw>.
BTW: this is now gcc version 4.0.2 20050725 (prerelease) (Debian 4.0.1-3) on ia64, but I've seen it with gcc 4.0.1 on ia64, too.
This is not a gcc bug, you cannot declare a lablel in an inline-asm that is going to be exposed. You can see the issue on any target by: struct cl_module_destroyer { inline cl_module_destroyer () { __asm__("\nthis_symbol_is_defined_once_or_twice:"); } }; cl_module_destroyer a; void g(void) { cl_module_destroyer a1; }
(In reply to comment #2) > This is not a gcc bug, you cannot declare a lablel in an inline-asm that is going to be exposed. Is there a reference of some sort? I was unable to find one with google. > You can see the issue on any target by: > struct cl_module_destroyer { > inline cl_module_destroyer () > { > __asm__("\nthis_symbol_is_defined_once_or_twice:"); > } > }; > > cl_module_destroyer a; > void g(void) > { > cl_module_destroyer a1; > } Please illuminate me why this is the same situation. I can vaguely understand how in the latter case the compiler ends up with two labels. But this appears to be quite different from the original situation where there's only one object to destroy.
(In reply to comment #3) > (In reply to comment #2) > > This is not a gcc bug, you cannot declare a lablel in an inline-asm that is > going to be exposed. > > Is there a reference of some sort? I was unable to find one with google. No, just a general rule as inline-asms will be copied when inlined or cloned. What is happening here is clonning is happening so we generate two copies of that function. > Please illuminate me why this is the same situation. I can vaguely understand > how in the latter case the compiler ends up with two labels. But this appears > to be quite different from the original situation where there's only one object > to destroy. Only one object to destroy but the constructor is cloned which is defined by the C++ abi.
(In reply to comment #2) > This is not a gcc bug, you cannot declare a lablel in an inline-asm that is going to be exposed. Okay then, but would adding __attribute__((visibility("hidden"))) to the game prevent the function from being cloned? It doesn't seem to help! I don't see any reason why the ABI calls for a clone of that function if its visibility is declared hidden.
(In reply to comment #5) > Okay then, but would adding __attribute__((visibility("hidden"))) to the game > prevent the function from being cloned? It doesn't seem to help! I don't see > any reason why the ABI calls for a clone of that function if its visibility is > declared hidden. Because constructors are cloned as needed by the IA64 C++ ABI. visibility hidden only goes across shared library boundaries and not function boundaries. When more optimizations are added to gcc, you will end up the same thing on any and all targets.