diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2014-09-05 21:27:52 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2014-09-05 21:27:52 +0000 |
| commit | d31dc048ca01fbeb4cee31189d8a4e5ca41a5a44 (patch) | |
| tree | ee307e23933ce4a73c9fe16c0e03d446abda027a /llvm/lib | |
| parent | 4bce548a6bb96d8cc14eaa4a3bd95c9a14a64c5e (diff) | |
| download | bcm5719-llvm-d31dc048ca01fbeb4cee31189d8a4e5ca41a5a44.tar.gz bcm5719-llvm-d31dc048ca01fbeb4cee31189d8a4e5ca41a5a44.zip | |
Fix pr20078.
When linking llvm.global_ctors with the optional third element we have to handle
it specially and only copy the elements whose keys were also copied.
llvm-svn: 217281
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Linker/LinkModules.cpp | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp index 5c26b2610b1..98114ca2e2f 100644 --- a/llvm/lib/Linker/LinkModules.cpp +++ b/llvm/lib/Linker/LinkModules.cpp @@ -1223,14 +1223,34 @@ static void getArrayElements(Constant *C, SmallVectorImpl<Constant*> &Dest) { void ModuleLinker::linkAppendingVarInit(const AppendingVarInfo &AVI) { // Merge the initializer. - SmallVector<Constant*, 16> Elements; - getArrayElements(AVI.DstInit, Elements); + SmallVector<Constant *, 16> DstElements; + getArrayElements(AVI.DstInit, DstElements); - Constant *SrcInit = MapValue(AVI.SrcInit, ValueMap, RF_None, &TypeMap, &ValMaterializer); - getArrayElements(SrcInit, Elements); + SmallVector<Constant *, 16> SrcElements; + getArrayElements(AVI.SrcInit, SrcElements); ArrayType *NewType = cast<ArrayType>(AVI.NewGV->getType()->getElementType()); - AVI.NewGV->setInitializer(ConstantArray::get(NewType, Elements)); + + StringRef Name = AVI.NewGV->getName(); + bool IsNewStructor = + (Name == "llvm.global_ctors" || Name == "llvm.global_dtors") && + cast<StructType>(NewType->getElementType())->getNumElements() == 3; + + for (auto *V : SrcElements) { + if (IsNewStructor) { + Constant *Key = V->getAggregateElement(2); + if (DoNotLinkFromSource.count(Key)) + continue; + } + DstElements.push_back( + MapValue(V, ValueMap, RF_None, &TypeMap, &ValMaterializer)); + } + if (IsNewStructor) { + NewType = ArrayType::get(NewType->getElementType(), DstElements.size()); + AVI.NewGV->mutateType(PointerType::get(NewType, 0)); + } + + AVI.NewGV->setInitializer(ConstantArray::get(NewType, DstElements)); } /// linkGlobalInits - Update the initializers in the Dest module now that all |

