summaryrefslogtreecommitdiff
path: root/gcc/lto-symtab.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2013-05-17 22:20:58 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2013-05-17 22:20:58 +0000
commitfc8456b4c99f339cd782b0990af3a7c107c9ced4 (patch)
tree53d9b1d7619f8f399786efc4b2699b0c661f580d /gcc/lto-symtab.c
parent59651d3b2414f63afae9bbf4da992c4789fbe6f1 (diff)
downloadgcc-fc8456b4c99f339cd782b0990af3a7c107c9ced4.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@199041 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/lto-symtab.c')
-rw-r--r--gcc/lto-symtab.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c
index a004eea24fd..8091d36193e 100644
--- a/gcc/lto-symtab.c
+++ b/gcc/lto-symtab.c
@@ -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;