diff options
author | Jan Hubicka <jh@suse.cz> | 2012-05-19 17:26:30 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2012-05-19 15:26:30 +0000 |
commit | 38e55ac9e0ee61b20b52115171e67d3c3e497a02 (patch) | |
tree | df46674937cbe724d4b48f02646392b55d6cdb37 | |
parent | c44c2088f77877c43b110c508bbfec492ba487a7 (diff) | |
download | gcc-38e55ac9e0ee61b20b52115171e67d3c3e497a02.zip gcc-38e55ac9e0ee61b20b52115171e67d3c3e497a02.tar.gz gcc-38e55ac9e0ee61b20b52115171e67d3c3e497a02.tar.bz2 |
* cgraphunit.c (handle_alias_pairs): Cleanup; handle all types of aliases.
From-SVN: r187680
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 87 |
2 files changed, 45 insertions, 46 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b648c70..63b7674 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2012-05-18 Jan Hubicka <jh@suse.cz> + * cgraphunit.c (handle_alias_pairs): Cleanup; handle all types of aliases. + +2012-05-18 Jan Hubicka <jh@suse.cz> + * cgraphbuild.c (record_reference): Update. * lto-cgraph.c (lto_output_varpool_node): External vars are not in other partition even if they are not output diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 7dae2c8..7cd9fdf 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1030,52 +1030,15 @@ handle_alias_pairs (void) { alias_pair *p; unsigned i; - struct cgraph_node *target_node; - struct cgraph_node *src_node; - struct varpool_node *target_vnode; for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);) { - if (TREE_CODE (p->decl) == FUNCTION_DECL - && (target_node = cgraph_node_for_asm (p->target)) != NULL) - { - src_node = cgraph_get_node (p->decl); - if (src_node && src_node->local.finalized) - cgraph_reset_node (src_node); - /* Normally EXTERNAL flag is used to mark external inlines, - however for aliases it seems to be allowed to use it w/o - any meaning. See gcc.dg/attr-alias-3.c - However for weakref we insist on EXTERNAL flag being set. - See gcc.dg/attr-alias-5.c */ - if (DECL_EXTERNAL (p->decl)) - DECL_EXTERNAL (p->decl) - = lookup_attribute ("weakref", - DECL_ATTRIBUTES (p->decl)) != NULL; - cgraph_create_function_alias (p->decl, target_node->symbol.decl); - VEC_unordered_remove (alias_pair, alias_pairs, i); - } - else if (TREE_CODE (p->decl) == VAR_DECL - && (target_vnode = varpool_node_for_asm (p->target)) != NULL) - { - /* Normally EXTERNAL flag is used to mark external inlines, - however for aliases it seems to be allowed to use it w/o - any meaning. See gcc.dg/attr-alias-3.c - However for weakref we insist on EXTERNAL flag being set. - See gcc.dg/attr-alias-5.c */ - if (DECL_EXTERNAL (p->decl)) - DECL_EXTERNAL (p->decl) - = lookup_attribute ("weakref", - DECL_ATTRIBUTES (p->decl)) != NULL; - varpool_create_variable_alias (p->decl, target_vnode->symbol.decl); - VEC_unordered_remove (alias_pair, alias_pairs, i); - } + symtab_node target_node = symtab_node_for_asm (p->target); + /* Weakrefs with target not defined in current unit are easy to handle; they behave just as external variables except we need to note the alias flag to later output the weakref pseudo op into asm file. */ - else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL - && (TREE_CODE (p->decl) == FUNCTION_DECL - ? (varpool_node_for_asm (p->target) == NULL) - : (cgraph_node_for_asm (p->target) == NULL))) + 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; @@ -1083,15 +1046,47 @@ handle_alias_pairs (void) varpool_get_node (p->decl)->alias = true; DECL_EXTERNAL (p->decl) = 1; VEC_unordered_remove (alias_pair, alias_pairs, i); + continue; } - else + else if (!target_node) { - if (dump_file) - fprintf (dump_file, "Unhandled alias %s->%s\n", - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p->decl)), - IDENTIFIER_POINTER (p->target)); + error ("%q+D aliased to undefined symbol %qE", p->decl, p->target); + VEC_unordered_remove (alias_pair, alias_pairs, i); + continue; + } + + /* Normally EXTERNAL flag is used to mark external inlines, + however for aliases it seems to be allowed to use it w/o + any meaning. See gcc.dg/attr-alias-3.c + However for weakref we insist on EXTERNAL flag being set. + See gcc.dg/attr-alias-5.c */ + if (DECL_EXTERNAL (p->decl)) + DECL_EXTERNAL (p->decl) + = lookup_attribute ("weakref", + DECL_ATTRIBUTES (p->decl)) != NULL; - i++; + if (TREE_CODE (p->decl) == FUNCTION_DECL + && target_node && symtab_function_p (target_node)) + { + struct cgraph_node *src_node = cgraph_get_node (p->decl); + if (src_node && src_node->local.finalized) + cgraph_reset_node (src_node); + cgraph_create_function_alias (p->decl, target_node->symbol.decl); + VEC_unordered_remove (alias_pair, alias_pairs, i); + } + else if (TREE_CODE (p->decl) == VAR_DECL + && target_node && symtab_variable_p (target_node)) + { + varpool_create_variable_alias (p->decl, target_node->symbol.decl); + VEC_unordered_remove (alias_pair, alias_pairs, i); + } + else + { + error ("%q+D alias in between function and variable is not supported", + p->decl); + warning (0, "%q+D aliased declaration", + target_node->symbol.decl); + VEC_unordered_remove (alias_pair, alias_pairs, i); } } } |