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 | b69fcb89052b3d468e8cf03a7cb76ec5aa25bee5 (patch) | |
tree | 57c891036852c8253c4afefdb4382b73304c07a8 /lib/Linker | |
parent | 09c685ffbc6065c98e2cb5e0988683b6ab0510ba (diff) | |
download | external_llvm-b69fcb89052b3d468e8cf03a7cb76ec5aa25bee5.zip external_llvm-b69fcb89052b3d468e8cf03a7cb76ec5aa25bee5.tar.gz external_llvm-b69fcb89052b3d468e8cf03a7cb76ec5aa25bee5.tar.bz2 |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41174 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Linker')
-rw-r--r-- | lib/Linker/LinkModules.cpp | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 462a4b7..85caa20 100644 --- a/lib/Linker/LinkModules.cpp +++ b/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)); |