aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Linker/LinkModules.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Linker/LinkModules.cpp')
-rw-r--r--llvm/lib/Linker/LinkModules.cpp22
1 files changed, 19 insertions, 3 deletions
diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp
index 97d6f8cd8075..efdbc49cdf47 100644
--- a/llvm/lib/Linker/LinkModules.cpp
+++ b/llvm/lib/Linker/LinkModules.cpp
@@ -177,9 +177,25 @@ bool ModuleLinker::computeResultingSelectionKind(StringRef ComdatName,
// Go with Dst.
LinkFromSrc = false;
break;
- case Comdat::SelectionKind::NoDeduplicate:
- return emitError("Linking COMDATs named '" + ComdatName +
- "': nodeduplicate has been violated!");
+ case Comdat::SelectionKind::NoDeduplicate: {
+ const GlobalVariable *DstGV;
+ const GlobalVariable *SrcGV;
+ if (getComdatLeader(DstM, ComdatName, DstGV) ||
+ getComdatLeader(*SrcM, ComdatName, SrcGV))
+ return true;
+
+ if (SrcGV->isWeakForLinker()) {
+ // Go with Dst.
+ LinkFromSrc = false;
+ } else if (DstGV->isWeakForLinker()) {
+ // Go with Src.
+ LinkFromSrc = true;
+ } else {
+ return emitError("Linking COMDATs named '" + ComdatName +
+ "': nodeduplicate has been violated!");
+ }
+ break;
+ }
case Comdat::SelectionKind::ExactMatch:
case Comdat::SelectionKind::Largest:
case Comdat::SelectionKind::SameSize: {