* cgraphunit.c (handle_alias_pairs): Cleanup; handle all types of aliases.
From-SVN: r187680
This commit is contained in:
parent
c44c2088f7
commit
38e55ac9e0
2 changed files with 45 additions and 46 deletions
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue