Bug 56297 - LTO: multiple definition error with global register variables
Summary: LTO: multiple definition error with global register variables
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: lto (show other bugs)
Version: 4.8.0
: P3 minor
Target Milestone: ---
Assignee: Richard Biener
URL:
Keywords: link-failure, lto
Depends on:
Blocks:
 
Reported: 2013-02-12 12:33 UTC by Dmitry Gorbachev
Modified: 2013-02-12 16:23 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-02-12 00:00:00


Attachments
Testcase (176 bytes, text/plain)
2013-02-12 12:33 UTC, Dmitry Gorbachev
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dmitry Gorbachev 2013-02-12 12:33:32 UTC
Created attachment 29424 [details]
Testcase

This testcase causes "multiple definition of 'esp'" error (note that esp has a fixed role, there is no need to reserve it).
Comment 1 Richard Biener 2013-02-12 13:39:15 UTC
Confirmed.  We put

register int i asm ("esp");

into the LTO symbol table.  Oops.  The GCC symtab and the partition contains

(gdb) call debug_symtab_node (node)
*esp/0 (*esp) @0x7ffff6e1a068
  Type: variable
  Visibility: force_output public
  References: 
  Referring: main/1 (read)
  Availability: overwritable
  Varpool flags: analyzed finalized

not sure if we want to put global hardregs into the symtab at all ...
(certainly not in the LTO symbol table we feed to the linker).
Thus, maybe

Index: gcc/lto-streamer-out.c
===================================================================
--- gcc/lto-streamer-out.c      (revision 195973)
+++ gcc/lto-streamer-out.c      (working copy)
@@ -1166,7 +1166,8 @@ write_symbol (struct streamer_tree_cache
   if (!TREE_PUBLIC (t)
       || is_builtin_fn (t)
       || DECL_ABSTRACT (t)
-      || TREE_CODE (t) == RESULT_DECL)
+      || TREE_CODE (t) == RESULT_DECL
+      || (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t)))
     return;
 
   gcc_assert (TREE_CODE (t) == VAR_DECL

?  At least it "works" with that change.

Testing it.
Comment 2 Richard Biener 2013-02-12 13:46:52 UTC
GCC 4.7 says

/tmp/ccQAPnYJ.o (symbol from plugin): In function `esp':
(.text+0x0): multiple definition of `esp'
/tmp/ccihIbJc.o (symbol from plugin):(.text+0x0): first defined here
In file included from foo.c:6:0,
                 from :0:
bar.c:1:14: warning: register of 'i' used for multiple global register variables [enabled by default]
In file included from :0:0:
foo.c:1:14: note: conflicts with 'i'
collect2: error: ld returned 1 exit status

with trunk we lost that (bogus) warning.  Even when using two different
variable names.
Comment 3 Richard Biener 2013-02-12 15:14:37 UTC
Author: rguenth
Date: Tue Feb 12 15:14:32 2013
New Revision: 195979

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=195979
Log:
2013-02-12  Richard Biener  <rguenther@suse.de>

	PR lto/56297
	* lto-streamer-out.c (write_symbol): Do not output symbols
	for hard register variables.

	* gcc.dg/lto/pr56297_0.c: New testcase.
	* gcc.dg/lto/pr56297_0.c: Likewise.

Added:
    trunk/gcc/testsuite/gcc.dg/lto/pr56297_0.c
    trunk/gcc/testsuite/gcc.dg/lto/pr56297_1.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/lto-streamer-out.c
    trunk/gcc/testsuite/ChangeLog
Comment 4 Richard Biener 2013-02-12 15:16:11 UTC
Fixed for 4.8.
Comment 5 Jan Hubicka 2013-02-12 16:23:37 UTC
> Confirmed.  We put
> 
> register int i asm ("esp");
> 
> into the LTO symbol table.  Oops.  The GCC symtab and the partition contains
> 
> (gdb) call debug_symtab_node (node)
> *esp/0 (*esp) @0x7ffff6e1a068
>   Type: variable
>   Visibility: force_output public
>   References: 
>   Referring: main/1 (read)
>   Availability: overwritable
>   Varpool flags: analyzed finalized
> 
> not sure if we want to put global hardregs into the symtab at all ...
> (certainly not in the LTO symbol table we feed to the linker).
> Thus, maybe
> 
> Index: gcc/lto-streamer-out.c
> ===================================================================
> --- gcc/lto-streamer-out.c      (revision 195973)
> +++ gcc/lto-streamer-out.c      (working copy)
> @@ -1166,7 +1166,8 @@ write_symbol (struct streamer_tree_cache
>    if (!TREE_PUBLIC (t)
>        || is_builtin_fn (t)
>        || DECL_ABSTRACT (t)
> -      || TREE_CODE (t) == RESULT_DECL)
> +      || TREE_CODE (t) == RESULT_DECL
> +      || (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t)))
>      return;
> 
>    gcc_assert (TREE_CODE (t) == VAR_DECL
> 
> ?  At least it "works" with that change.
> 
> Testing it.

Yeah, I suppose we ought to put those out of symbol table for 4.9. I have local patch for that.

Honza