Bug 23345 - Assembler message: symbol is already defined
Summary: Assembler message: symbol is already defined
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.0.1
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-08-11 22:00 UTC by Richard B. Kreckel
Modified: 2005-08-12 22:00 UTC (History)
1 user (show)

See Also:
Host: ia64-linux-gnu
Target: ia64-linux-gnu
Build: ia64-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Richard B. Kreckel 2005-08-11 22:00:07 UTC
$ 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>.
Comment 1 Richard B. Kreckel 2005-08-11 22:02:39 UTC
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.
Comment 2 Andrew Pinski 2005-08-11 22:06:18 UTC
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;
}
Comment 3 Richard B. Kreckel 2005-08-11 22:42:14 UTC
(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.
Comment 4 Andrew Pinski 2005-08-11 23:40:43 UTC
(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.
Comment 5 Richard B. Kreckel 2005-08-12 21:57:32 UTC
(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.
Comment 6 Andrew Pinski 2005-08-12 22:00:21 UTC
(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.