diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index dca523c7ab1..765fcc88235 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -596,10 +596,14 @@ void ModuleLinker::computeTypeMapping() { // it had the same type, it would have been renamed to "%foo.42 = { i32 }". std::vector<StructType*> SrcStructTypes; SrcM->findUsedStructTypes(SrcStructTypes); - SmallPtrSet<StructType*, 32> SrcStructTypesSet(SrcStructTypes.begin(), SrcStructTypes.end()); - + + std::vector<StructType*> DstStructTypes; + DstM->findUsedStructTypes(DstStructTypes); + SmallPtrSet<StructType*, 32> DstStructTypesSet(DstStructTypes.begin(), + DstStructTypes.end()); + for (unsigned i = 0, e = SrcStructTypes.size(); i != e; ++i) { StructType *ST = SrcStructTypes[i]; if (!ST->hasName()) continue; @@ -612,9 +616,24 @@ void ModuleLinker::computeTypeMapping() { // Check to see if the destination module has a struct with the prefix name. if (StructType *DST = DstM->getTypeByName(ST->getName().substr(0, DotPos))) - // Don't use it if this actually came from the source module. They're in - // the same LLVMContext after all. - if (!SrcStructTypesSet.count(DST)) + // Don't use it if this actually came from the source module. They're in + // the same LLVMContext after all. Also don't use it unless the type is + // actually used in the destination module. This can happen in situations + // like this: + // + // Module A Module B + // -------- -------- + // %Z = type { %A } %B = type { %C.1 } + // %A = type { %B.1, [7 x i8] } %C.1 = type { i8* } + // %B.1 = type { %C } %A.2 = type { %B.3, [5 x i8] } + // %C = type { i8* } %B.3 = type { %C.1 } + // + // When we link Module B with Module A, the '%B' in Module B is + // used. However, that would then use '%C.1'. But when we process '%C.1', + // we prefer to take the '%C' version. So we are then left with both + // '%C.1' and '%C' being used for the same types. This leads to some + // variables using one type and some using the other. + if (!SrcStructTypesSet.count(DST) && DstStructTypesSet.count(DST)) TypeMap.addTypeMapping(DST, ST); } @@ -1313,6 +1332,6 @@ bool Linker::LinkModules(Module *Dest, Module *Src, unsigned Mode, if (ErrorMsg) *ErrorMsg = TheLinker.ErrorMsg; return true; } - + return false; }