diff options
author | Jan Hubicka <jh@suse.cz> | 2013-06-04 21:44:51 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2013-06-04 19:44:51 +0000 |
commit | aaae719df3df968a3a5cf5a03a8fb9d1889f1a50 (patch) | |
tree | ad227d417e6731c387197201d9fbbd5439ef5d3d /gcc/symtab.c | |
parent | 107eea2ca48ec70e64787340d3e07c8b59ab0e79 (diff) | |
download | gcc-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.c | 51 |
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) |