From 194c2cef8a0036dd4e6295d048f37d6130f92389 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Sat, 5 Jul 2008 23:03:21 +0000 Subject: [PATCH] Properly link alias and function decls. This fixes PR2146 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53154 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Linker/LinkModules.cpp | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index e02f7fe44c6..a915a8b873a 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -899,21 +899,30 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, for (Module::const_iterator I = Src->begin(), E = Src->end(); I != E; ++I) { const Function *SF = I; // SrcFunction - Function *DF = 0; + GlobalValue *DGV = 0; Value *MappedDF; // If this function is internal or has no name, it doesn't participate in // linkage. if (SF->hasName() && !SF->hasInternalLinkage()) { // Check to see if may have to link the function. - DF = Dest->getFunction(SF->getName()); - if (DF && DF->hasInternalLinkage()) - DF = 0; + DGV = Dest->getFunction(SF->getName()); } - + + // Check to see if may have to link the function with the alias + if (!DGV && SF->hasName() && !SF->hasInternalLinkage()) { + DGV = Dest->getNamedAlias(SF->getName()); + if (DGV && DGV->getType() != SF->getType()) + // If types don't agree due to opaque types, try to resolve them. + RecursiveResolveTypes(SF->getType(), DGV->getType()); + } + + if (DGV && DGV->hasInternalLinkage()) + DGV = 0; + // If there is no linkage to be performed, just bring over SF without // modifying it. - if (DF == 0) { + if (DGV == 0) { // Function does not already exist, simply insert an function signature // identical to SF into the dest module. Function *NewDF = Function::Create(SF->getFunctionType(), @@ -930,9 +939,19 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src, // ... and remember this mapping... ValueMap[SF] = NewDF; continue; + } else if (GlobalAlias *DGA = dyn_cast(DGV)) { + // SF is global, but DF is alias. The only valid mapping is when SF is + // external declaration, which is effectively a no-op. + if (!SF->isDeclaration()) + return Error(Err, "Function-Alias Collision on '" + SF->getName() + + "': symbol multiple defined"); + + // Make sure to remember this mapping... + ValueMap[SF] = DGA; + continue; } - - + + Function* DF = cast(DGV); // If types don't agree because of opaque, try to resolve them. if (SF->getType() != DF->getType()) RecursiveResolveTypes(SF->getType(), DF->getType());