Hi, symtab nodes are (ab)used to prevent removal of debug info from functions that appear as abstract origins of other functions. I am not sure if this is the best way to do so, but the code is fundamentaly broken on few places and it seems to make sense to get it working before thinking what would be really proper representation (for LTO the fact that debug info has nodes comes handy)
This is first part of the patch that makes us to handle abstract function correctly in the symtab. Bootstrapped/regtested x86_64-linux, will commit it shortly. Honza * lto-symtab.c (lto_symtab_merge_symbols): Merge duplicated nodes for abstract functions. * cgraph.h (symtab_real_symbol_p): Abstract declarations are not real symbols. Index: lto-symtab.c =================================================================== --- lto-symtab.c (revision 201250) +++ lto-symtab.c (working copy) @@ -599,6 +599,13 @@ lto_symtab_merge_symbols (void) && (cnode2 = cgraph_get_node (node->symbol.decl)) && cnode2 != cnode) lto_cgraph_replace_node (cnode2, cnode); + + /* Abstract functions may have duplicated cgraph nodes attached; + remove them. */ + else if (cnode && DECL_ABSTRACT (cnode->symbol.decl) + && (cnode2 = cgraph_get_node (node->symbol.decl)) + && cnode2 != cnode) + cgraph_remove_node (cnode2); symtab_insert_node_to_hashtable ((symtab_node)node); } } Index: cgraph.h =================================================================== --- cgraph.h (revision 201250) +++ cgraph.h (working copy) @@ -1347,13 +1347,13 @@ symtab_real_symbol_p (symtab_node node) { struct cgraph_node *cnode; + if (DECL_ABSTRACT (node->symbol.decl)) + return false; if (!is_a <cgraph_node> (node)) return true; cnode = cgraph (node); if (cnode->global.inlined_to) return false; - if (cnode->abstract_and_needed) - return false; return true; } #endif /* GCC_CGRAPH_H */