ComdatsChosen;
bool getComdatResult(const Comdat *SrcC, Comdat::SelectionKind &SK,
bool &LinkFromSrc);
+ // Keep track of the global value members of each comdat in source.
+ DenseMap<const Comdat *, std::vector<GlobalValue *>> ComdatMembers;
/// Given a global in the source module, return the global in the
/// destination module that is being linked to, if any.
// since it would cause global constructors/destructors to be
// executed multiple times. This should have already been handled
// by linkGlobalValueProto.
- assert(false && "Cannot import appending linkage variable");
+ llvm_unreachable("Cannot import appending linkage variable");
case GlobalValue::InternalLinkage:
case GlobalValue::PrivateLinkage:
std::tie(SK, LinkFromSrc) = ComdatsChosen[SC];
C = DstM->getOrInsertComdat(SC->getName());
C->setSelectionKind(SK);
+ ComdatMembers[SC].push_back(SGV);
} else if (DGV) {
if (shouldLinkFromSource(LinkFromSrc, *DGV, *SGV))
return true;
bool ModuleLinker::linkGlobalValueBody(GlobalValue &Src) {
Value *Dst = ValueMap[&Src];
assert(Dst);
+ if (const Comdat *SC = Src.getComdat()) {
+ // To ensure that we don't generate an incomplete comdat group,
+ // we must materialize and map in any other members that are not
+ // yet materialized in Dst, which also ensures their definitions
+ // are linked in. Otherwise, linkonce and other lazy linked GVs will
+ // not be materialized if they aren't referenced.
+ for (auto *SGV : ComdatMembers[SC]) {
+ if (ValueMap[SGV])
+ continue;
+ Value *NewV = ValMaterializer.materializeValueFor(SGV);
+ ValueMap[SGV] = NewV;
+ }
+ }
if (shouldInternalizeLinkedSymbols())
if (auto *DGV = dyn_cast<GlobalValue>(Dst))
DGV->setLinkage(GlobalValue::InternalLinkage);
NamedMDNode *DestNMD = DstM->getOrInsertNamedMetadata(NMD.getName());
// Add Src elements into Dest node.
for (const MDNode *op : NMD.operands())
- DestNMD->addOperand(MapMetadata(op, ValueMap, RF_MoveDistinctMDs,
- &TypeMap, &ValMaterializer));
+ DestNMD->addOperand(MapMetadata(
+ op, ValueMap, RF_MoveDistinctMDs | RF_NullMapMissingGlobalValues,
+ &TypeMap, &ValMaterializer));
}
}