diff options
author | Jan Hubicka <jh@suse.cz> | 2013-05-18 00:20:58 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2013-05-17 22:20:58 +0000 |
commit | e01c7cca63aa448ccf625c5201d8d9d31f2633b3 (patch) | |
tree | 53d9b1d7619f8f399786efc4b2699b0c661f580d /gcc | |
parent | 8ee05051146a7a571a2a65b3205854def9a757ba (diff) | |
download | gcc-e01c7cca63aa448ccf625c5201d8d9d31f2633b3.zip gcc-e01c7cca63aa448ccf625c5201d8d9d31f2633b3.tar.gz gcc-e01c7cca63aa448ccf625c5201d8d9d31f2633b3.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cgraph.c | 2 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 16 | ||||
-rw-r--r-- | gcc/lto-symtab.c | 56 |
4 files changed, 76 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7fce202..5cc09ae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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> diff --git a/gcc/cgraph.c b/gcc/cgraph.c index dff3916..899f65c 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -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)); diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 7fa8055..6ebf8d4 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -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)); } diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c index a004eea..8091d36 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; |