From: Chris Lattner Date: Mon, 9 Jun 2008 07:47:34 +0000 (+0000) Subject: use 'continue' to make the function linker simpler. When linking a strong X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=822143e6f7271c6546434d2d0b3da7a29711020d;p=oota-llvm.git use 'continue' to make the function linker simpler. When linking a strong function into a weak function, zap the weak function body so that the strong one overrides it. This fixes PR2410 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52135 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index a5e9a3e3e8f..2f0cda6c41f 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -916,20 +916,26 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, // the declarations, we aren't adding anything. if (SF->hasDLLImportLinkage()) { if (DF->isDeclaration()) { - ValueMap.insert(std::make_pair(SF, DF)); + ValueMap[SF] = DF; DF->setLinkage(SF->getLinkage()); - } + } } else { ValueMap[SF] = DF; - } - } else if (DF->isDeclaration() && !DF->hasDLLImportLinkage()) { - // If DF is external but SF is not... - // Link the external functions, update linkage qualifiers + } + continue; + } + + // If DF is external but SF is not, link the external functions, update + // linkage qualifiers. + if (DF->isDeclaration() && !DF->hasDLLImportLinkage()) { ValueMap.insert(std::make_pair(SF, DF)); DF->setLinkage(SF->getLinkage()); - } else if (SF->hasWeakLinkage() || SF->hasLinkOnceLinkage() || - SF->hasCommonLinkage()) { - // At this point we know that DF has LinkOnce, Weak, or External* linkage. + continue; + } + + // At this point we know that DF has LinkOnce, Weak, or External* linkage. + if (SF->hasWeakLinkage() || SF->hasLinkOnceLinkage() || + SF->hasCommonLinkage()) { ValueMap[SF] = DF; // Linkonce+Weak = Weak @@ -938,24 +944,34 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, (SF->hasWeakLinkage() || SF->hasCommonLinkage())) || DF->hasExternalWeakLinkage()) DF->setLinkage(SF->getLinkage()); - } else if (DF->hasWeakLinkage() || DF->hasLinkOnceLinkage() || - DF->hasCommonLinkage()) { + continue; + } + + if (DF->hasWeakLinkage() || DF->hasLinkOnceLinkage() || + DF->hasCommonLinkage()) { // At this point we know that SF has LinkOnce or External* linkage. ValueMap[SF] = DF; - if (!SF->hasLinkOnceLinkage() && !SF->hasExternalWeakLinkage()) - // Don't inherit linkonce & external weak linkage + + // If the source function has stronger linkage than the destination, + // its body and linkage should override ours. + if (!SF->hasLinkOnceLinkage() && !SF->hasExternalWeakLinkage()) { + // Don't inherit linkonce & external weak linkage. DF->setLinkage(SF->getLinkage()); - } else if (SF->getLinkage() != DF->getLinkage()) { - return Error(Err, "Functions named '" + SF->getName() + - "' have different linkage specifiers!"); - } else if (SF->hasExternalLinkage()) { - // The function is defined identically in both modules!! + DF->deleteBody(); + } + continue; + } + + if (SF->getLinkage() != DF->getLinkage()) + return Error(Err, "Functions named '" + SF->getName() + + "' have different linkage specifiers!"); + + // The function is defined identically in both modules! + if (SF->hasExternalLinkage()) return Error(Err, "Function '" + ToStr(SF->getFunctionType(), Src) + "':\"" + SF->getName() + "\" - Function is already defined!"); - } else { - assert(0 && "Unknown linkage configuration found!"); - } + assert(0 && "Unknown linkage configuration found!"); } return false; }