aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2008-09-09 18:23:48 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2008-09-09 18:23:48 +0000
commit832b2a9cd8870211bf2d347d7b435beacbb06c8d (patch)
tree2c8499487682972aae62e62ecf86c320f70f4045
parentbff66b0c6c8266a6f9ba6c9bd5d2541a4d4c6ec9 (diff)
Fix incorrect linker behaviour: we shouldn't resolve weak aliases.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55997 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/GlobalAlias.h6
-rw-r--r--lib/Linker/LinkModules.cpp4
-rw-r--r--lib/VMCore/Globals.cpp10
3 files changed, 15 insertions, 5 deletions
diff --git a/include/llvm/GlobalAlias.h b/include/llvm/GlobalAlias.h
index 6dba21bf60..1081fc675f 100644
--- a/include/llvm/GlobalAlias.h
+++ b/include/llvm/GlobalAlias.h
@@ -76,8 +76,10 @@ public:
/// resolveAliasedGlobal() - This method tries to ultimately resolve the alias
/// by going through the aliasing chain and trying to find the very last
- /// global. Returns NULL if a cycle was found.
- const GlobalValue* resolveAliasedGlobal() const;
+ /// global. Returns NULL if a cycle was found. If traverseWeak is true, then
+ /// the whole chain aliasing chain is traversed, otherwise - only strong
+ /// aliases.
+ const GlobalValue* resolveAliasedGlobal(bool traverseWeak = true) const;
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const GlobalAlias *) { return true; }
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index 3b319c2840..f4ebe6b10c 100644
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -1169,8 +1169,8 @@ static bool LinkAppendingVars(Module *M,
static bool ResolveAliases(Module *Dest) {
for (Module::alias_iterator I = Dest->alias_begin(), E = Dest->alias_end();
I != E; ++I)
- if (const GlobalValue *GV = I->resolveAliasedGlobal())
- if (!GV->isDeclaration())
+ if (const GlobalValue *GV = I->resolveAliasedGlobal(/*traverseWeak*/ false))
+ if (GV != I && !GV->isDeclaration())
I->replaceAllUsesWith(const_cast<GlobalValue*>(GV));
return false;
diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp
index 7340f1532f..e55cb5a5ac 100644
--- a/lib/VMCore/Globals.cpp
+++ b/lib/VMCore/Globals.cpp
@@ -248,13 +248,21 @@ const GlobalValue *GlobalAlias::getAliasedGlobal() const {
return 0;
}
-const GlobalValue *GlobalAlias::resolveAliasedGlobal() const {
+const GlobalValue *GlobalAlias::resolveAliasedGlobal(bool traverseWeak) const {
SmallPtrSet<const GlobalValue*, 3> Visited;
+ // Check if we need to stop early.
+ if (!traverseWeak && hasWeakLinkage())
+ return this;
+
const GlobalValue *GV = getAliasedGlobal();
Visited.insert(GV);
+ // Iterate over aliasing chain, stopping on weak alias if necessary.
while (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) {
+ if (traverseWeak && GA->hasWeakLinkage())
+ break;
+
GV = GA->getAliasedGlobal();
if (!Visited.insert(GV))