diff options
author | Chris Lattner <sabre@nondot.org> | 2007-08-19 22:22:54 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-08-19 22:22:54 +0000 |
commit | 1cc79985cdc2dda9ccedfb1bff597cd5d311d8ad (patch) | |
tree | 9b6f84fa26fe35882c544a83fd6d5b5433b399d0 /llvm/lib/Linker/LinkModules.cpp | |
parent | 10f03a644ae337f2f917e478d94f2e4a7f97fc45 (diff) | |
download | bcm5719-llvm-1cc79985cdc2dda9ccedfb1bff597cd5d311d8ad.tar.gz bcm5719-llvm-1cc79985cdc2dda9ccedfb1bff597cd5d311d8ad.zip |
Fix PR1611 - Visibility should be ignored for a declaration
when a definition's visibility is different. Likewise, the
visibility of two declarations mismatching is not an error.
llvm-svn: 41174
Diffstat (limited to 'llvm/lib/Linker/LinkModules.cpp')
-rw-r--r-- | llvm/lib/Linker/LinkModules.cpp | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp index 462a4b7c662..85caa20464c 100644 --- a/llvm/lib/Linker/LinkModules.cpp +++ b/llvm/lib/Linker/LinkModules.cpp @@ -440,8 +440,9 @@ static bool GetLinkageResult(GlobalValue *Dest, GlobalValue *Src, // Check visibility if (Dest && Src->getVisibility() != Dest->getVisibility()) - return Error(Err, "Linking globals named '" + Src->getName() + - "': symbols have different visibilities!"); + if (!Src->isDeclaration() && !Dest->isDeclaration()) + return Error(Err, "Linking globals named '" + Src->getName() + + "': symbols have different visibilities!"); return false; } @@ -651,9 +652,13 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, // Check visibility if (DF && !DF->hasInternalLinkage() && - SF->getVisibility() != DF->getVisibility()) - return Error(Err, "Linking functions named '" + SF->getName() + - "': symbols have different visibilities!"); + SF->getVisibility() != DF->getVisibility()) { + // If one is a prototype, ignore its visibility. Prototypes are always + // overridden by the definition. + if (!SF->isDeclaration() && !DF->isDeclaration()) + return Error(Err, "Linking functions named '" + SF->getName() + + "': symbols have different visibilities!"); + } if (DF && DF->getType() != SF->getType()) { if (DF->isDeclaration() && !SF->isDeclaration()) { @@ -695,7 +700,7 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, } } else if (!DF || SF->hasInternalLinkage() || DF->hasInternalLinkage()) { // Function does not already exist, simply insert an function signature - // identical to SF into the dest module... + // identical to SF into the dest module. Function *NewDF = new Function(SF->getFunctionType(), SF->getLinkage(), SF->getName(), Dest); CopyGVAttributes(NewDF, SF); @@ -724,6 +729,8 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, // Link the external functions, update linkage qualifiers ValueMap.insert(std::make_pair(SF, DF)); DF->setLinkage(SF->getLinkage()); + // Visibility of prototype is overridden by vis of definition. + DF->setVisibility(SF->getVisibility()); } else if (SF->hasWeakLinkage() || SF->hasLinkOnceLinkage()) { // At this point we know that DF has LinkOnce, Weak, or External* linkage. ValueMap.insert(std::make_pair(SF, DF)); |