diff --git a/llvm/lib/Transforms/Utils/Linker.cpp b/llvm/lib/Transforms/Utils/Linker.cpp index f6b1916db445..24449ea9f691 100644 --- a/llvm/lib/Transforms/Utils/Linker.cpp +++ b/llvm/lib/Transforms/Utils/Linker.cpp @@ -59,9 +59,10 @@ static const StructType *getST(const PATypeHolder &TH) { // recurses down into derived types, merging the used types if the parent types // are compatible. // -static bool RecursiveResolveTypes(const PATypeHolder &DestTy, - const PATypeHolder &SrcTy, - SymbolTable *DestST, const std::string &Name){ +static bool RecursiveResolveTypesI(const PATypeHolder &DestTy, + const PATypeHolder &SrcTy, + SymbolTable *DestST, const std::string &Name, + std::vector > &Pointers) { const Type *SrcTyT = SrcTy.get(); const Type *DestTyT = DestTy.get(); if (DestTyT == SrcTyT) return false; // If already equal, noop @@ -81,8 +82,9 @@ static bool RecursiveResolveTypes(const PATypeHolder &DestTy, cast(SrcTyT)->isVarArg()) return true; for (unsigned i = 0, e = getFT(DestTy)->getNumContainedTypes(); i != e; ++i) - if (RecursiveResolveTypes(getFT(DestTy)->getContainedType(i), - getFT(SrcTy)->getContainedType(i), DestST, "")) + if (RecursiveResolveTypesI(getFT(DestTy)->getContainedType(i), + getFT(SrcTy)->getContainedType(i), DestST, "", + Pointers)) return true; return false; } @@ -90,8 +92,9 @@ static bool RecursiveResolveTypes(const PATypeHolder &DestTy, if (getST(DestTy)->getNumContainedTypes() != getST(SrcTy)->getNumContainedTypes()) return 1; for (unsigned i = 0, e = getST(DestTy)->getNumContainedTypes(); i != e; ++i) - if (RecursiveResolveTypes(getST(DestTy)->getContainedType(i), - getST(SrcTy)->getContainedType(i), DestST, "")) + if (RecursiveResolveTypesI(getST(DestTy)->getContainedType(i), + getST(SrcTy)->getContainedType(i), DestST, "", + Pointers)) return true; return false; } @@ -99,18 +102,40 @@ static bool RecursiveResolveTypes(const PATypeHolder &DestTy, const ArrayType *DAT = cast(DestTy.get()); const ArrayType *SAT = cast(SrcTy.get()); if (DAT->getNumElements() != SAT->getNumElements()) return true; - return RecursiveResolveTypes(DAT->getElementType(), SAT->getElementType(), - DestST, ""); + return RecursiveResolveTypesI(DAT->getElementType(), SAT->getElementType(), + DestST, "", Pointers); + } + case Type::PointerTyID: { + // If this is a pointer type, check to see if we have already seen it. If + // so, we are in a recursive branch. Cut off the search now. We cannot use + // an associative container for this search, because the type pointers (keys + // in the container) change whenever types get resolved... + // + for (unsigned i = 0, e = Pointers.size(); i != e; ++i) + if (Pointers[i].first == DestTy) + return Pointers[i].second != SrcTy; + + // Otherwise, add the current pointers to the vector to stop recursion on + // this pair. + Pointers.push_back(std::make_pair(DestTyT, SrcTyT)); + bool Result = + RecursiveResolveTypesI(cast(DestTy.get())->getElementType(), + cast(SrcTy.get())->getElementType(), + DestST, "", Pointers); + Pointers.pop_back(); + return Result; } - case Type::PointerTyID: - return RecursiveResolveTypes( - cast(DestTy.get())->getElementType(), - cast(SrcTy.get())->getElementType(), - DestST, ""); default: assert(0 && "Unexpected type!"); return true; } } +static bool RecursiveResolveTypes(const PATypeHolder &DestTy, + const PATypeHolder &SrcTy, + SymbolTable *DestST, const std::string &Name){ + std::vector > PointerTypes; + return RecursiveResolveTypesI(DestTy, SrcTy, DestST, Name, PointerTypes); +} + // LinkTypes - Go through the symbol table of the Src module and see if any // types are named in the src module that are not named in the Dst module.