From aaae719df3df968a3a5cf5a03a8fb9d1889f1a50 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Tue, 4 Jun 2013 21:44:51 +0200 Subject: attr-alias.c: New testcase. * gcc.dg/tree-ssa/attr-alias.c: New testcase. * ipa-inline.c (update_caller_keys): Fix availability test. (update_callee_keys): Likewise. * symtab.c (symtab_alias_ultimate_target): Make availaiblity logic to follow ELF standard. From-SVN: r199670 --- gcc/symtab.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) (limited to 'gcc/symtab.c') diff --git a/gcc/symtab.c b/gcc/symtab.c index af8e70b..02d3da1 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -834,19 +834,64 @@ symtab_node_availability (symtab_node node) symtab_node symtab_alias_ultimate_target (symtab_node node, enum availability *availability) { + bool weakref_p = false; + + if (!node->symbol.alias) + { + if (availability) + *availability = symtab_node_availability (node); + return node; + } + + /* To determine visibility of the target, we follow ELF semantic of aliases. + Here alias is an alternative assembler name of a given definition. Its + availablity prevails the availablity of its target (i.e. static alias of + weak definition is available. + + Weakref is a different animal (and not part of ELF per se). It is just + alternative name of a given symbol used within one complation unit + and is translated prior hitting the object file. It inherits the + visibility of its target (i.e. weakref of non-overwritable definition + is non-overwritable, while weakref of weak definition is weak). + + If we ever get into supporting targets with different semantics, a target + hook will be needed here. */ + if (availability) - *availability = symtab_node_availability (node); + { + weakref_p = DECL_EXTERNAL (node->symbol.decl) && node->symbol.alias; + if (!weakref_p) + *availability = symtab_node_availability (node); + else + *availability = AVAIL_LOCAL; + } while (node) { if (node->symbol.alias && node->symbol.analyzed) node = symtab_alias_target (node); else - return node; - if (node && availability) + { + if (!availability) + ; + else if (node->symbol.analyzed) + { + if (weakref_p) + { + enum availability a = symtab_node_availability (node); + if (a < *availability) + *availability = a; + } + } + else + *availability = AVAIL_NOT_AVAILABLE; + return node; + } + if (node && availability && weakref_p) { enum availability a = symtab_node_availability (node); if (a < *availability) *availability = a; + weakref_p = DECL_EXTERNAL (node->symbol.decl) && node->symbol.alias; } } if (availability) -- cgit v1.1