<div dir="ltr">Sorry, I reverted this in r221096 because it introduces a heap-use-after-free which was causing havoc with asan bots as well as who knows what other crashes during LTO builds.<div><br></div><div>I included the full ASan trace in that commit log, but let me know if you can't reproduce it. It reproduced trivially for me with the CMake LLVM_USE_SANITZER=Address build mode, and the Linker regression tests.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Oct 31, 2014 at 4:10 PM, Rafael Espindola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rafael<br>
Date: Fri Oct 31 18:10:07 2014<br>
New Revision: 221014<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=221014&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=221014&view=rev</a><br>
Log:<br>
Refactor duplicated code in liking GlobalValues.<br>
<br>
There is quiet a bit of logic that is common to any GlobalValue but was<br>
duplicated for Functions, GlobalVariables and GlobalAliases.<br>
<br>
While at it, merge visibility even when comdats are used, fixing pr21415.<br>
<br>
Modified:<br>
llvm/trunk/lib/Linker/LinkModules.cpp<br>
llvm/trunk/test/Linker/Inputs/visibility.ll<br>
llvm/trunk/test/Linker/visibility.ll<br>
<br>
Modified: llvm/trunk/lib/Linker/LinkModules.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=221014&r1=221013&r2=221014&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=221014&r1=221013&r2=221014&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Linker/LinkModules.cpp (original)<br>
+++ llvm/trunk/lib/Linker/LinkModules.cpp Fri Oct 31 18:10:07 2014<br>
@@ -453,13 +453,6 @@ namespace {<br>
bool getComdatResult(const Comdat *SrcC, Comdat::SelectionKind &SK,<br>
bool &LinkFromSrc);<br>
<br>
- /// This analyzes the two global values and determines what the result will<br>
- /// look like in the destination module.<br>
- bool getLinkageResult(GlobalValue *Dest, const GlobalValue *Src,<br>
- GlobalValue::LinkageTypes <,<br>
- GlobalValue::VisibilityTypes &Vis,<br>
- bool &LinkFromSrc);<br>
-<br>
/// Given a global in the source module, return the global in the<br>
/// destination module that is being linked to, if any.<br>
GlobalValue *getLinkedToGlobal(const GlobalValue *SrcGV) {<br>
@@ -488,9 +481,15 @@ namespace {<br>
<br>
bool linkAppendingVarProto(GlobalVariable *DstGV,<br>
const GlobalVariable *SrcGV);<br>
- bool linkGlobalProto(const GlobalVariable *SrcGV);<br>
- bool linkFunctionProto(Function *SrcF);<br>
- bool linkAliasProto(GlobalAlias *SrcA);<br>
+<br>
+ bool linkGlobalValueProto(GlobalValue *GV);<br>
+ GlobalValue *linkGlobalVariableProto(const GlobalVariable *SGVar,<br>
+ GlobalValue *DGV, bool LinkFromSrc);<br>
+ GlobalValue *linkFunctionProto(const Function *SF, GlobalValue *DGV,<br>
+ bool LinkFromSrc);<br>
+ GlobalValue *linkGlobalAliasProto(const GlobalAlias *SGA, GlobalValue *DGV,<br>
+ bool LinkFromSrc);<br>
+<br>
bool linkModuleFlagsMetadata();<br>
<br>
void linkAppendingVarInit(const AppendingVarInfo &AVI);<br>
@@ -688,6 +687,12 @@ bool ModuleLinker::getComdatResult(const<br>
bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,<br>
const GlobalValue &Dest,<br>
const GlobalValue &Src) {<br>
+ // We always have to add Src if it has appending linkage.<br>
+ if (Src.hasAppendingLinkage()) {<br>
+ LinkFromSrc = true;<br>
+ return false;<br>
+ }<br>
+<br>
bool SrcIsDeclaration = Src.isDeclarationForLinker();<br>
bool DestIsDeclaration = Dest.isDeclarationForLinker();<br>
<br>
@@ -757,36 +762,6 @@ bool ModuleLinker::shouldLinkFromSource(<br>
"': symbol multiply defined!");<br>
}<br>
<br>
-/// This analyzes the two global values and determines what the result will look<br>
-/// like in the destination module. In particular, it computes the resultant<br>
-/// linkage type and visibility, computes whether the global in the source<br>
-/// should be copied over to the destination (replacing the existing one), and<br>
-/// computes whether this linkage is an error or not.<br>
-bool ModuleLinker::getLinkageResult(GlobalValue *Dest, const GlobalValue *Src,<br>
- GlobalValue::LinkageTypes <,<br>
- GlobalValue::VisibilityTypes &Vis,<br>
- bool &LinkFromSrc) {<br>
- assert(Dest && "Must have two globals being queried");<br>
- assert(!Src->hasLocalLinkage() &&<br>
- "If Src has internal linkage, Dest shouldn't be set!");<br>
-<br>
- if (shouldLinkFromSource(LinkFromSrc, *Dest, *Src))<br>
- return true;<br>
-<br>
- if (LinkFromSrc)<br>
- LT = Src->getLinkage();<br>
- else<br>
- LT = Dest->getLinkage();<br>
-<br>
- // Compute the visibility. We follow the rules in the System V Application<br>
- // Binary Interface.<br>
- assert(!GlobalValue::isLocalLinkage(LT) &&<br>
- "Symbols with local linkage should not be merged");<br>
- Vis = isLessConstraining(Src->getVisibility(), Dest->getVisibility()) ?<br>
- Dest->getVisibility() : Src->getVisibility();<br>
- return false;<br>
-}<br>
-<br>
/// Loop over all of the linked values to compute type mappings. For example,<br>
/// if we link "extern Foo *x" and "Foo *x = NULL", then we have two struct<br>
/// types 'Foo' but one got renamed when the module was loaded into the same<br>
@@ -1010,256 +985,164 @@ bool ModuleLinker::linkAppendingVarProto<br>
return false;<br>
}<br>
<br>
-/// Loop through the global variables in the src module and merge them into the<br>
-/// dest module.<br>
-bool ModuleLinker::linkGlobalProto(const GlobalVariable *SGV) {<br>
+bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) {<br>
GlobalValue *DGV = getLinkedToGlobal(SGV);<br>
- llvm::Optional<GlobalValue::VisibilityTypes> NewVisibility;<br>
+ bool LinkFromSrc = true;<br>
+ Comdat *C = nullptr;<br>
+ GlobalValue::VisibilityTypes Visibility = SGV->getVisibility();<br>
bool HasUnnamedAddr = SGV->hasUnnamedAddr();<br>
- unsigned Alignment = SGV->getAlignment();<br>
<br>
- bool LinkFromSrc = false;<br>
- Comdat *DC = nullptr;<br>
if (const Comdat *SC = SGV->getComdat()) {<br>
Comdat::SelectionKind SK;<br>
std::tie(SK, LinkFromSrc) = ComdatsChosen[SC];<br>
- DC = DstM->getOrInsertComdat(SC->getName());<br>
- DC->setSelectionKind(SK);<br>
+ C = DstM->getOrInsertComdat(SC->getName());<br>
+ C->setSelectionKind(SK);<br>
+ } else if (DGV) {<br>
+ if (shouldLinkFromSource(LinkFromSrc, *DGV, *SGV))<br>
+ return true;<br>
}<br>
<br>
- if (DGV) {<br>
- if (!DC) {<br>
- // Concatenation of appending linkage variables is magic and handled later.<br>
- if (DGV->hasAppendingLinkage() || SGV->hasAppendingLinkage())<br>
- return linkAppendingVarProto(cast<GlobalVariable>(DGV), SGV);<br>
-<br>
- // Determine whether linkage of these two globals follows the source<br>
- // module's definition or the destination module's definition.<br>
- GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage;<br>
- GlobalValue::VisibilityTypes NV;<br>
- if (getLinkageResult(DGV, SGV, NewLinkage, NV, LinkFromSrc))<br>
- return true;<br>
- NewVisibility = NV;<br>
- HasUnnamedAddr = HasUnnamedAddr && DGV->hasUnnamedAddr();<br>
- if (DGV->hasCommonLinkage() && SGV->hasCommonLinkage())<br>
- Alignment = std::max(Alignment, DGV->getAlignment());<br>
- else if (!LinkFromSrc)<br>
- Alignment = DGV->getAlignment();<br>
-<br>
- // If we're not linking from the source, then keep the definition that we<br>
- // have.<br>
- if (!LinkFromSrc) {<br>
- // Special case for const propagation.<br>
- if (GlobalVariable *DGVar = dyn_cast<GlobalVariable>(DGV)) {<br>
- DGVar->setAlignment(Alignment);<br>
-<br>
- if (DGVar->isDeclaration() && !SGV->isConstant())<br>
- DGVar->setConstant(false);<br>
- }<br>
-<br>
- // Set calculated linkage, visibility and unnamed_addr.<br>
- DGV->setLinkage(NewLinkage);<br>
- DGV->setVisibility(*NewVisibility);<br>
- DGV->setUnnamedAddr(HasUnnamedAddr);<br>
- }<br>
- }<br>
+ if (!LinkFromSrc) {<br>
+ // Track the source global so that we don't attempt to copy it over when<br>
+ // processing global initializers.<br>
+ DoNotLinkFromSource.insert(SGV);<br>
<br>
- if (!LinkFromSrc) {<br>
+ if (DGV)<br>
// Make sure to remember this mapping.<br>
- ValueMap[SGV] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGV->getType()));<br>
-<br>
- // Track the source global so that we don't attempt to copy it over when<br>
- // processing global initializers.<br>
- DoNotLinkFromSource.insert(SGV);<br>
+ ValueMap[SGV] =<br>
+ ConstantExpr::getBitCast(DGV, TypeMap.get(SGV->getType()));<br>
+ }<br>
<br>
- return false;<br>
- }<br>
+ if (DGV) {<br>
+ Visibility = isLessConstraining(Visibility, DGV->getVisibility())<br>
+ ? DGV->getVisibility()<br>
+ : Visibility;<br>
+ HasUnnamedAddr = HasUnnamedAddr && DGV->hasUnnamedAddr();<br>
}<br>
<br>
- // If the Comdat this variable was inside of wasn't selected, skip it.<br>
- if (DC && !DGV && !LinkFromSrc) {<br>
- DoNotLinkFromSource.insert(SGV);<br>
+ if (!LinkFromSrc && !DGV)<br>
return false;<br>
+<br>
+ GlobalValue *NewGV;<br>
+ if (auto *SGVar = dyn_cast<GlobalVariable>(SGV)) {<br>
+ NewGV = linkGlobalVariableProto(SGVar, DGV, LinkFromSrc);<br>
+ if (!NewGV)<br>
+ return true;<br>
+ } else if (auto *SF = dyn_cast<Function>(SGV)) {<br>
+ NewGV = linkFunctionProto(SF, DGV, LinkFromSrc);<br>
+ } else {<br>
+ NewGV = linkGlobalAliasProto(cast<GlobalAlias>(SGV), DGV, LinkFromSrc);<br>
}<br>
<br>
- // No linking to be performed or linking from the source: simply create an<br>
- // identical version of the symbol over in the dest module... the<br>
- // initializer will be filled in later by LinkGlobalInits.<br>
- GlobalVariable *NewDGV =<br>
- new GlobalVariable(*DstM, TypeMap.get(SGV->getType()->getElementType()),<br>
- SGV->isConstant(), SGV->getLinkage(), /*init*/nullptr,<br>
- SGV->getName(), /*insertbefore*/nullptr,<br>
- SGV->getThreadLocalMode(),<br>
- SGV->getType()->getAddressSpace());<br>
- // Propagate alignment, visibility and section info.<br>
- copyGVAttributes(NewDGV, SGV);<br>
- NewDGV->setAlignment(Alignment);<br>
- if (NewVisibility)<br>
- NewDGV->setVisibility(*NewVisibility);<br>
- NewDGV->setUnnamedAddr(HasUnnamedAddr);<br>
+ if (NewGV) {<br>
+ if (NewGV != DGV)<br>
+ copyGVAttributes(NewGV, SGV);<br>
<br>
- if (DC)<br>
- NewDGV->setComdat(DC);<br>
+ NewGV->setUnnamedAddr(HasUnnamedAddr);<br>
+ NewGV->setVisibility(Visibility);<br>
<br>
- if (DGV) {<br>
- DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDGV, DGV->getType()));<br>
- DGV->eraseFromParent();<br>
+ if (auto *NewGO = dyn_cast<GlobalObject>(NewGV)) {<br>
+ if (C)<br>
+ NewGO->setComdat(C);<br>
+ }<br>
+<br>
+ // Make sure to remember this mapping.<br>
+ if (NewGV != DGV) {<br>
+ if (DGV) {<br>
+ DGV->replaceAllUsesWith(<br>
+ ConstantExpr::getBitCast(NewGV, DGV->getType()));<br>
+ DGV->eraseFromParent();<br>
+ }<br>
+ ValueMap[SGV] = NewGV;<br>
+ }<br>
}<br>
<br>
- // Make sure to remember this mapping.<br>
- ValueMap[SGV] = NewDGV;<br>
return false;<br>
}<br>
<br>
-/// Link the function in the source module into the destination module if<br>
-/// needed, setting up mapping information.<br>
-bool ModuleLinker::linkFunctionProto(Function *SF) {<br>
- GlobalValue *DGV = getLinkedToGlobal(SF);<br>
- llvm::Optional<GlobalValue::VisibilityTypes> NewVisibility;<br>
- bool HasUnnamedAddr = SF->hasUnnamedAddr();<br>
-<br>
- bool LinkFromSrc = false;<br>
- Comdat *DC = nullptr;<br>
- if (const Comdat *SC = SF->getComdat()) {<br>
- Comdat::SelectionKind SK;<br>
- std::tie(SK, LinkFromSrc) = ComdatsChosen[SC];<br>
- DC = DstM->getOrInsertComdat(SC->getName());<br>
- DC->setSelectionKind(SK);<br>
- }<br>
+/// Loop through the global variables in the src module and merge them into the<br>
+/// dest module.<br>
+GlobalValue *ModuleLinker::linkGlobalVariableProto(const GlobalVariable *SGVar,<br>
+ GlobalValue *DGV,<br>
+ bool LinkFromSrc) {<br>
+ unsigned Alignment = 0;<br>
+ bool ClearConstant = false;<br>
<br>
if (DGV) {<br>
- if (!DC) {<br>
- GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage;<br>
- GlobalValue::VisibilityTypes NV;<br>
- if (getLinkageResult(DGV, SF, NewLinkage, NV, LinkFromSrc))<br>
- return true;<br>
- NewVisibility = NV;<br>
- HasUnnamedAddr = HasUnnamedAddr && DGV->hasUnnamedAddr();<br>
-<br>
- if (!LinkFromSrc) {<br>
- // Set calculated linkage<br>
- DGV->setLinkage(NewLinkage);<br>
- DGV->setVisibility(*NewVisibility);<br>
- DGV->setUnnamedAddr(HasUnnamedAddr);<br>
- }<br>
+ // Concatenation of appending linkage variables is magic and handled later.<br>
+ if (DGV->hasAppendingLinkage()) {<br>
+ if (linkAppendingVarProto(cast<GlobalVariable>(DGV), SGVar))<br>
+ return nullptr;<br>
+ return DGV;<br>
}<br>
<br>
- if (!LinkFromSrc) {<br>
- // Make sure to remember this mapping.<br>
- ValueMap[SF] = ConstantExpr::getBitCast(DGV, TypeMap.get(SF->getType()));<br>
-<br>
- // Track the function from the source module so we don't attempt to remap<br>
- // it.<br>
- DoNotLinkFromSource.insert(SF);<br>
+ if (DGV->hasCommonLinkage() && SGVar->hasCommonLinkage())<br>
+ Alignment = std::max(SGVar->getAlignment(), DGV->getAlignment());<br>
<br>
- return false;<br>
+ auto *DGVar = dyn_cast<GlobalVariable>(DGV);<br>
+ if (!SGVar->isConstant() || (DGVar && !DGVar->isConstant()))<br>
+ ClearConstant = true;<br>
+ }<br>
+<br>
+ if (!LinkFromSrc) {<br>
+ if (auto *NewGVar = dyn_cast<GlobalVariable>(DGV)) {<br>
+ if (Alignment)<br>
+ NewGVar->setAlignment(Alignment);<br>
+ if (NewGVar->isDeclaration() && ClearConstant)<br>
+ NewGVar->setConstant(false);<br>
}<br>
+ return DGV;<br>
}<br>
<br>
+ // No linking to be performed or linking from the source: simply create an<br>
+ // identical version of the symbol over in the dest module... the<br>
+ // initializer will be filled in later by LinkGlobalInits.<br>
+ GlobalVariable *NewDGV = new GlobalVariable(<br>
+ *DstM, TypeMap.get(SGVar->getType()->getElementType()),<br>
+ SGVar->isConstant(), SGVar->getLinkage(), /*init*/ nullptr,<br>
+ SGVar->getName(), /*insertbefore*/ nullptr, SGVar->getThreadLocalMode(),<br>
+ SGVar->getType()->getAddressSpace());<br>
+<br>
+ if (Alignment)<br>
+ NewDGV->setAlignment(Alignment);<br>
+<br>
+ return NewDGV;<br>
+}<br>
+<br>
+/// Link the function in the source module into the destination module if<br>
+/// needed, setting up mapping information.<br>
+GlobalValue *ModuleLinker::linkFunctionProto(const Function *SF,<br>
+ GlobalValue *DGV,<br>
+ bool LinkFromSrc) {<br>
+ if (!LinkFromSrc)<br>
+ return DGV;<br>
+<br>
// If the function is to be lazily linked, don't create it just yet.<br>
// The ValueMaterializerTy will deal with creating it if it's used.<br>
if (!DGV && (SF->hasLocalLinkage() || SF->hasLinkOnceLinkage() ||<br>
SF->hasAvailableExternallyLinkage())) {<br>
DoNotLinkFromSource.insert(SF);<br>
- return false;<br>
- }<br>
-<br>
- // If the Comdat this function was inside of wasn't selected, skip it.<br>
- if (DC && !DGV && !LinkFromSrc) {<br>
- DoNotLinkFromSource.insert(SF);<br>
- return false;<br>
+ return nullptr;<br>
}<br>
<br>
// If there is no linkage to be performed or we are linking from the source,<br>
// bring SF over.<br>
- Function *NewDF = Function::Create(TypeMap.get(SF->getFunctionType()),<br>
- SF->getLinkage(), SF->getName(), DstM);<br>
- copyGVAttributes(NewDF, SF);<br>
- if (NewVisibility)<br>
- NewDF->setVisibility(*NewVisibility);<br>
- NewDF->setUnnamedAddr(HasUnnamedAddr);<br>
-<br>
- if (DC)<br>
- NewDF->setComdat(DC);<br>
-<br>
- if (DGV) {<br>
- // Any uses of DF need to change to NewDF, with cast.<br>
- DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDF, DGV->getType()));<br>
- DGV->eraseFromParent();<br>
- }<br>
-<br>
- ValueMap[SF] = NewDF;<br>
- return false;<br>
+ return Function::Create(TypeMap.get(SF->getFunctionType()), SF->getLinkage(),<br>
+ SF->getName(), DstM);<br>
}<br>
<br>
/// Set up prototypes for any aliases that come over from the source module.<br>
-bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) {<br>
- GlobalValue *DGV = getLinkedToGlobal(SGA);<br>
- llvm::Optional<GlobalValue::VisibilityTypes> NewVisibility;<br>
- bool HasUnnamedAddr = SGA->hasUnnamedAddr();<br>
-<br>
- bool LinkFromSrc = false;<br>
- Comdat *DC = nullptr;<br>
- if (const Comdat *SC = SGA->getComdat()) {<br>
- Comdat::SelectionKind SK;<br>
- std::tie(SK, LinkFromSrc) = ComdatsChosen[SC];<br>
- DC = DstM->getOrInsertComdat(SC->getName());<br>
- DC->setSelectionKind(SK);<br>
- }<br>
-<br>
- if (DGV) {<br>
- if (!DC) {<br>
- GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage;<br>
- GlobalValue::VisibilityTypes NV;<br>
- if (getLinkageResult(DGV, SGA, NewLinkage, NV, LinkFromSrc))<br>
- return true;<br>
- NewVisibility = NV;<br>
- HasUnnamedAddr = HasUnnamedAddr && DGV->hasUnnamedAddr();<br>
-<br>
- if (!LinkFromSrc) {<br>
- // Set calculated linkage.<br>
- DGV->setLinkage(NewLinkage);<br>
- DGV->setVisibility(*NewVisibility);<br>
- DGV->setUnnamedAddr(HasUnnamedAddr);<br>
- }<br>
- }<br>
-<br>
- if (!LinkFromSrc) {<br>
- // Make sure to remember this mapping.<br>
- ValueMap[SGA] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGA->getType()));<br>
-<br>
- // Track the alias from the source module so we don't attempt to remap it.<br>
- DoNotLinkFromSource.insert(SGA);<br>
-<br>
- return false;<br>
- }<br>
- }<br>
-<br>
- // If the Comdat this alias was inside of wasn't selected, skip it.<br>
- if (DC && !DGV && !LinkFromSrc) {<br>
- DoNotLinkFromSource.insert(SGA);<br>
- return false;<br>
- }<br>
+GlobalValue *ModuleLinker::linkGlobalAliasProto(const GlobalAlias *SGA,<br>
+ GlobalValue *DGV,<br>
+ bool LinkFromSrc) {<br>
+ if (!LinkFromSrc)<br>
+ return DGV;<br>
<br>
// If there is no linkage to be performed or we're linking from the source,<br>
// bring over SGA.<br>
auto *PTy = cast<PointerType>(TypeMap.get(SGA->getType()));<br>
- auto *NewDA =<br>
- GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(),<br>
- SGA->getLinkage(), SGA->getName(), DstM);<br>
- copyGVAttributes(NewDA, SGA);<br>
- if (NewVisibility)<br>
- NewDA->setVisibility(*NewVisibility);<br>
- NewDA->setUnnamedAddr(HasUnnamedAddr);<br>
-<br>
- if (DGV) {<br>
- // Any uses of DGV need to change to NewDA, with cast.<br>
- DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDA, DGV->getType()));<br>
- DGV->eraseFromParent();<br>
- }<br>
-<br>
- ValueMap[SGA] = NewDA;<br>
- return false;<br>
+ return GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(),<br>
+ SGA->getLinkage(), SGA->getName(), DstM);<br>
}<br>
<br>
static void getArrayElements(const Constant *C,<br>
@@ -1599,7 +1482,7 @@ bool ModuleLinker::run() {<br>
// initializers (which could refer to functions not yet mapped over).<br>
for (Module::global_iterator I = SrcM->global_begin(),<br>
E = SrcM->global_end(); I != E; ++I)<br>
- if (linkGlobalProto(I))<br>
+ if (linkGlobalValueProto(I))<br>
return true;<br>
<br>
// Link the functions together between the two modules, without doing function<br>
@@ -1608,13 +1491,13 @@ bool ModuleLinker::run() {<br>
// all of the global values that may be referenced are available in our<br>
// ValueMap.<br>
for (Module::iterator I = SrcM->begin(), E = SrcM->end(); I != E; ++I)<br>
- if (linkFunctionProto(I))<br>
+ if (linkGlobalValueProto(I))<br>
return true;<br>
<br>
// If there were any aliases, link them now.<br>
for (Module::alias_iterator I = SrcM->alias_begin(),<br>
E = SrcM->alias_end(); I != E; ++I)<br>
- if (linkAliasProto(I))<br>
+ if (linkGlobalValueProto(I))<br>
return true;<br>
<br>
for (unsigned i = 0, e = AppendingVars.size(); i != e; ++i)<br>
<br>
Modified: llvm/trunk/test/Linker/Inputs/visibility.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/Inputs/visibility.ll?rev=221014&r1=221013&r2=221014&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/Inputs/visibility.ll?rev=221014&r1=221013&r2=221014&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/Linker/Inputs/visibility.ll (original)<br>
+++ llvm/trunk/test/Linker/Inputs/visibility.ll Fri Oct 31 18:10:07 2014<br>
@@ -1,7 +1,10 @@<br>
+$c1 = comdat any<br>
+<br>
; Variables<br>
@v1 = weak hidden global i32 0<br>
@v2 = weak protected global i32 0<br>
@v3 = weak hidden global i32 0<br>
+@v4 = hidden global i32 1, comdat $c1<br>
<br>
; Aliases<br>
@a1 = weak hidden alias i32* @v1<br>
<br>
Modified: llvm/trunk/test/Linker/visibility.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/visibility.ll?rev=221014&r1=221013&r2=221014&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/visibility.ll?rev=221014&r1=221013&r2=221014&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/Linker/visibility.ll (original)<br>
+++ llvm/trunk/test/Linker/visibility.ll Fri Oct 31 18:10:07 2014<br>
@@ -4,16 +4,21 @@<br>
; The values in this file are strong, the ones in Inputs/visibility.ll are weak,<br>
; but we should still get the visibility from them.<br>
<br>
+<br>
+$c1 = comdat any<br>
+<br>
; Variables<br>
-; CHECK: @v1 = hidden global i32 0<br>
+; CHECK-DAG: @v1 = hidden global i32 0<br>
@v1 = global i32 0<br>
<br>
-; CHECK: @v2 = protected global i32 0<br>
+; CHECK-DAG: @v2 = protected global i32 0<br>
@v2 = global i32 0<br>
<br>
-; CHECK: @v3 = hidden global i32 0<br>
+; CHECK-DAG: @v3 = hidden global i32 0<br>
@v3 = protected global i32 0<br>
<br>
+; CHECK-DAG: @v4 = hidden global i32 1, comdat $c1<br>
+@v4 = global i32 1, comdat $c1<br>
<br>
; Aliases<br>
; CHECK: @a1 = hidden alias i32* @v1<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>