Hi,
so far we handled only aliases that looked sane by the new cgraph/varpool code.
This
patch should complette the transition and we now handle all aliases this way.
It also adds an error into case we decided to not handle - the
function<->variable
aliases.
Bootstrapped/regtested x86_64-linux, comitted.
I will followup with cleanups and removal of the new unreachable old alias
handling code.
Honza
* cgraphunit.c (handle_alias_pairs): Cleanup; handle all types of
aliases.
Index: cgraphunit.c
===================================================================
*** cgraphunit.c (revision 187678)
--- cgraphunit.c (working copy)
*************** handle_alias_pairs (void)
*** 1030,1081 ****
{
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);
! }
/* 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 (TREE_CODE (p->decl) == FUNCTION_DECL)
cgraph_get_create_node (p->decl)->alias = true;
--- 1030,1044 ----
{
alias_pair *p;
unsigned i;
for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p);)
{
! 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. */
! 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;
*************** handle_alias_pairs (void)
*** 1083,1097 ****
varpool_get_node (p->decl)->alias = true;
DECL_EXTERNAL (p->decl) = 1;
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++;
}
}
}
--- 1046,1092 ----
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
! {
! 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);
}
}
}