From: Jan Hubicka Date: Sat, 19 May 2012 15:26:30 +0000 (+0200) Subject: * cgraphunit.c (handle_alias_pairs): Cleanup; handle all types of aliases. X-Git-Tag: upstream/12.2.0~76208 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=38e55ac9e0ee61b20b52115171e67d3c3e497a02;p=platform%2Fupstream%2Fgcc.git * cgraphunit.c (handle_alias_pairs): Cleanup; handle all types of aliases. From-SVN: r187680 --- 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 + * cgraphunit.c (handle_alias_pairs): Cleanup; handle all types of aliases. + +2012-05-18 Jan Hubicka + * 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); } } }