From 38e55ac9e0ee61b20b52115171e67d3c3e497a02 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sat, 19 May 2012 17:26:30 +0200 Subject: [PATCH] * cgraphunit.c (handle_alias_pairs): Cleanup; handle all types of aliases. From-SVN: r187680 --- gcc/ChangeLog | 4 +++ gcc/cgraphunit.c | 87 +++++++++++++++++++++++------------------------- 2 files changed, 45 insertions(+), 46 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b648c7032b5..63b7674b2b2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +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. 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 if (!target_node) + { + 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; + + 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 { - if (dump_file) - fprintf (dump_file, "Unhandled alias %s->%s\n", - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p->decl)), - IDENTIFIER_POINTER (p->target)); - - i++; + 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); } } }