mirror of git://gcc.gnu.org/git/gcc.git
lto-symtab.c (lto_symtab_merge_cgraph_nodes): Resolve cross module weakrefs.
* lto-symtab.c (lto_symtab_merge_cgraph_nodes): Resolve cross module weakrefs. * cgraph.c (dump_cgraph_node): Do not ice on unresolved alias. * cgraphunit.c (handle_alias_pairs): Store target of unresolved weakrefs. (output_weakrefs): Update. From-SVN: r199041
This commit is contained in:
parent
8ee0505114
commit
e01c7cca63
|
|
@ -1,3 +1,11 @@
|
|||
2013-05-17 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* lto-symtab.c (lto_symtab_merge_cgraph_nodes): Resolve cross module
|
||||
weakrefs.
|
||||
* cgraph.c (dump_cgraph_node): Do not ice on unresolved alias.
|
||||
* cgraphunit.c (handle_alias_pairs): Store target of unresolved weakrefs.
|
||||
(output_weakrefs): Update.
|
||||
|
||||
2013-05-17 Po-Chun Chang <pchang9@cs.wisc.edu>
|
||||
Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
|
|
|
|||
|
|
@ -1558,7 +1558,7 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
|
|||
(int)node->thunk.virtual_value,
|
||||
(int)node->thunk.virtual_offset_p);
|
||||
}
|
||||
if (node->alias && node->thunk.alias)
|
||||
if (node->alias && node->thunk.alias && DECL_P (node->thunk.alias))
|
||||
{
|
||||
fprintf (f, " Alias of %s",
|
||||
lang_hooks.decl_printable_name (node->thunk.alias, 2));
|
||||
|
|
|
|||
|
|
@ -1069,9 +1069,17 @@ handle_alias_pairs (void)
|
|||
if (!target_node && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
|
||||
{
|
||||
if (TREE_CODE (p->decl) == FUNCTION_DECL)
|
||||
cgraph_get_create_node (p->decl)->alias = true;
|
||||
{
|
||||
struct cgraph_node *anode = cgraph_get_create_node (p->decl);
|
||||
anode->alias = true;
|
||||
anode->thunk.alias = p->target;
|
||||
}
|
||||
else
|
||||
varpool_get_node (p->decl)->alias = true;
|
||||
{
|
||||
struct varpool_node *anode = varpool_get_node (p->decl);
|
||||
anode->alias = true;
|
||||
anode->alias_of = p->target;
|
||||
}
|
||||
DECL_EXTERNAL (p->decl) = 1;
|
||||
alias_pairs->unordered_remove (i);
|
||||
continue;
|
||||
|
|
@ -1939,14 +1947,14 @@ output_weakrefs (void)
|
|||
&& !TREE_ASM_WRITTEN (node->symbol.decl)
|
||||
&& lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
|
||||
do_assemble_alias (node->symbol.decl,
|
||||
node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
|
||||
node->thunk.alias && DECL_P (node->thunk.alias) ? DECL_ASSEMBLER_NAME (node->thunk.alias)
|
||||
: get_alias_symbol (node->symbol.decl));
|
||||
FOR_EACH_VARIABLE (vnode)
|
||||
if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
|
||||
&& !TREE_ASM_WRITTEN (vnode->symbol.decl)
|
||||
&& lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
|
||||
do_assemble_alias (vnode->symbol.decl,
|
||||
vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
|
||||
vnode->alias_of && DECL_P (vnode->alias_of) ? DECL_ASSEMBLER_NAME (vnode->alias_of)
|
||||
: get_alias_symbol (vnode->symbol.decl));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -593,13 +593,67 @@ lto_symtab_merge_cgraph_nodes (void)
|
|||
|
||||
FOR_EACH_FUNCTION (cnode)
|
||||
{
|
||||
/* Resolve weakrefs to symbol defined in other unit. */
|
||||
if (!cnode->analyzed && cnode->thunk.alias && !DECL_P (cnode->thunk.alias))
|
||||
{
|
||||
symtab_node node = symtab_node_for_asm (cnode->thunk.alias);
|
||||
if (node && is_a <cgraph_node> (node))
|
||||
{
|
||||
struct cgraph_node *n;
|
||||
|
||||
for (n = cgraph (node); n && n->alias;
|
||||
n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
|
||||
if (n == cnode)
|
||||
{
|
||||
error ("function %q+D part of alias cycle", cnode->symbol.decl);
|
||||
cnode->alias = false;
|
||||
break;
|
||||
}
|
||||
if (cnode->alias)
|
||||
{
|
||||
cgraph_create_function_alias (cnode->symbol.decl, node->symbol.decl);
|
||||
ipa_record_reference ((symtab_node)cnode, (symtab_node)node,
|
||||
IPA_REF_ALIAS, NULL);
|
||||
cnode->analyzed = true;
|
||||
}
|
||||
}
|
||||
else if (node)
|
||||
error ("%q+D alias in between function and variable is not supported", cnode->symbol.decl);
|
||||
}
|
||||
if ((cnode->thunk.thunk_p || cnode->alias)
|
||||
&& cnode->thunk.alias)
|
||||
&& cnode->thunk.alias && DECL_P (cnode->thunk.alias))
|
||||
cnode->thunk.alias = lto_symtab_prevailing_decl (cnode->thunk.alias);
|
||||
cnode->symbol.aux = NULL;
|
||||
}
|
||||
FOR_EACH_VARIABLE (vnode)
|
||||
{
|
||||
/* Resolve weakrefs to symbol defined in other unit. */
|
||||
if (!vnode->analyzed && vnode->alias_of && !DECL_P (vnode->alias_of))
|
||||
{
|
||||
symtab_node node = symtab_node_for_asm (vnode->alias_of);
|
||||
if (node && is_a <cgraph_node> (node))
|
||||
{
|
||||
struct varpool_node *n;
|
||||
|
||||
for (n = varpool (node); n && n->alias;
|
||||
n = n->analyzed ? varpool_alias_aliased_node (n) : NULL)
|
||||
if (n == vnode)
|
||||
{
|
||||
error ("function %q+D part of alias cycle", vnode->symbol.decl);
|
||||
vnode->alias = false;
|
||||
break;
|
||||
}
|
||||
if (vnode->alias)
|
||||
{
|
||||
varpool_create_variable_alias (vnode->symbol.decl, node->symbol.decl);
|
||||
ipa_record_reference ((symtab_node)vnode, (symtab_node)node,
|
||||
IPA_REF_ALIAS, NULL);
|
||||
vnode->analyzed = true;
|
||||
}
|
||||
}
|
||||
else if (node)
|
||||
error ("%q+D alias in between function and variable is not supported", vnode->symbol.decl);
|
||||
}
|
||||
if (vnode->alias_of)
|
||||
vnode->alias_of = lto_symtab_prevailing_decl (vnode->alias_of);
|
||||
vnode->symbol.aux = NULL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue