diff options
author | Jan Hubicka <jh@suse.cz> | 2012-05-19 15:26:30 +0000 |
---|---|---|
committer | Jan Hubicka <jh@suse.cz> | 2012-05-19 15:26:30 +0000 |
commit | 8d931eb5bd3adcbc6f3d7a503735af600d59f3ef (patch) | |
tree | df46674937cbe724d4b48f02646392b55d6cdb37 /gcc/cgraphunit.c | |
parent | 2608e7d1a3ad2dd1795cb52f89e17dece9407e73 (diff) |
* cgraphunit.c (handle_alias_pairs): Cleanup; handle all types of aliases.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@187680 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cgraphunit.c')
-rw-r--r-- | gcc/cgraphunit.c | 87 |
1 files changed, 41 insertions, 46 deletions
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 7dae2c8e820..7cd9fdf02b1 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); } } } |