summaryrefslogtreecommitdiff
path: root/gcc/symtab.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2013-06-04 21:44:51 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2013-06-04 19:44:51 +0000
commitaaae719df3df968a3a5cf5a03a8fb9d1889f1a50 (patch)
treead227d417e6731c387197201d9fbbd5439ef5d3d /gcc/symtab.c
parent107eea2ca48ec70e64787340d3e07c8b59ab0e79 (diff)
downloadgcc-aaae719df3df968a3a5cf5a03a8fb9d1889f1a50.tar.gz
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
Diffstat (limited to 'gcc/symtab.c')
-rw-r--r--gcc/symtab.c51
1 files changed, 48 insertions, 3 deletions
diff --git a/gcc/symtab.c b/gcc/symtab.c
index af8e70bb02c..02d3da170ab 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)