* cgraphunit.c (handle_alias_pairs): Cleanup; handle all types of aliases.

From-SVN: r187680
This commit is contained in:
Jan Hubicka 2012-05-19 17:26:30 +02:00 committed by Jan Hubicka
parent c44c2088f7
commit 38e55ac9e0
2 changed files with 45 additions and 46 deletions

View File

@ -1,3 +1,7 @@
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.

View File

@ -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);
}
}
}