* 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> 2012-05-18 Jan Hubicka <jh@suse.cz>
* cgraphbuild.c (record_reference): Update. * cgraphbuild.c (record_reference): Update.

View File

@ -1030,52 +1030,15 @@ handle_alias_pairs (void)
{ {
alias_pair *p; alias_pair *p;
unsigned i; 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);) for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);)
{ {
if (TREE_CODE (p->decl) == FUNCTION_DECL symtab_node target_node = symtab_node_for_asm (p->target);
&& (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);
}
/* Weakrefs with target not defined in current unit are easy to handle; they /* 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 behave just as external variables except we need to note the alias flag
to later output the weakref pseudo op into asm file. */ to later output the weakref pseudo op into asm file. */
else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL if (!target_node && 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 (TREE_CODE (p->decl) == FUNCTION_DECL) if (TREE_CODE (p->decl) == FUNCTION_DECL)
cgraph_get_create_node (p->decl)->alias = true; cgraph_get_create_node (p->decl)->alias = true;
@ -1083,15 +1046,47 @@ handle_alias_pairs (void)
varpool_get_node (p->decl)->alias = true; varpool_get_node (p->decl)->alias = true;
DECL_EXTERNAL (p->decl) = 1; DECL_EXTERNAL (p->decl) = 1;
VEC_unordered_remove (alias_pair, alias_pairs, i); 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 else
{ {
if (dump_file) error ("%q+D alias in between function and variable is not supported",
fprintf (dump_file, "Unhandled alias %s->%s\n", p->decl);
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (p->decl)), warning (0, "%q+D aliased declaration",
IDENTIFIER_POINTER (p->target)); target_node->symbol.decl);
VEC_unordered_remove (alias_pair, alias_pairs, i);
i++;
} }
} }
} }