http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47274
Jan Hubicka <hubicka at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |dave.korn.cygwin at gmail | |dot com --- Comment #21 from Jan Hubicka <hubicka at gcc dot gnu.org> 2011-01-31 17:07:35 UTC --- Thanks. Looking at compilation time callgraphs, they are all as expected. At link time however, the resolution info seems however all wrong. That results in wrong merging. Not only for vars, but also for functions: main_test/7(-1) @0x4045f5b0 (asm: main_test) prevailing_def_ironly called by: main/6 (1.00 per call) calls: References: Refering this function: main_test/0(-1) @0x4045f000 (asm: main_test) analyzed 19 time, 12 benefit 13 size, 4 benefit externally_visible finalized inlinable called by: calls: abort/1 abort/1 abs/2 (1.00 per call) References: var:abs_called (read) Refering this function: The first node is main_test comming from main.c, the second is one comming from abd-1.c defining the function. The problem is that first one is defined as prevailing_def_ironly while it is not an definition, just use of the symbol. Correct would be to have PREVAILING_DEF_IRONLY on the second and PREEMTED_IR on the first. We probably should add sanity check that functions with PREVAILING_DEFs are always analyzed and vars finalized. As observer by Richard, it comes from resolution file already: abs-1.o 3 70 262910e5 PREEMPTED_IR main_test main.o 3 76 e5772d37 PREVAILING_DEF_IRONLY main_test should be the other way around I am quite convinced that we are seeing GNU LD bug and adding Dave Korn to CC thus. The other alternative would be that lto symbol table is output incorrectly at compilation time. You might try to experiment with NM's plugin support to try to dump LTO symbol table of main.o. I never tried it myself as I never really needed to dump LTO symbol table, but it should be supported now. But given that the code in write_symbol is quite straighforward: if (DECL_EXTERNAL (t)) { if (DECL_WEAK (t)) kind = GCCPK_WEAKUNDEF; else kind = GCCPK_UNDEF; } else { if (DECL_WEAK (t)) kind = GCCPK_WEAKDEF; else if (DECL_COMMON (t)) kind = GCCPK_COMMON; else kind = GCCPK_DEF; /* When something is defined, it should have node attached. */ gcc_assert (alias || TREE_CODE (t) != VAR_DECL || varpool_get_node (t)->finalized); gcc_assert (alias || TREE_CODE (t) != FUNCTION_DECL || (cgraph_get_node (t) && cgraph_get_node (t)->analyzed)); } (kind should be GCCPK_UNDEF for main_test in main.o) I would not expect bug to be on symbol streaming side.