mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[DI] Fix check that ignores loads related to assign_or_init and assign_by_wrapper
For cases where init accessor field has a nonmutating set we need ignore copies and borrows associated with load of "self" because they are going to be erased together with the setter application by DI.
This commit is contained in:
@@ -662,8 +662,27 @@ bool LifetimeChecker::shouldEmitError(const SILInstruction *Inst) {
|
||||
// This is safe to ignore because assign_by_wrapper/assign_or_init will
|
||||
// only be re-written to use the setter if the value is fully initialized.
|
||||
if (auto *load = dyn_cast<SingleValueInstruction>(Inst)) {
|
||||
if (auto Op = load->getSingleUse()) {
|
||||
if (auto PAI = dyn_cast<PartialApplyInst>(Op->getUser())) {
|
||||
auto isOnlyUsedByPartialApply =
|
||||
[&](const SingleValueInstruction *inst) -> PartialApplyInst * {
|
||||
Operand *result = nullptr;
|
||||
for (auto *op : inst->getUses()) {
|
||||
auto *user = op->getUser();
|
||||
|
||||
// Ignore copies, destroys and borrows because they'd be
|
||||
// erased together with the setter.
|
||||
if (isa<DestroyValueInst>(user) || isa<CopyValueInst>(user) ||
|
||||
isa<BeginBorrowInst>(user) || isa<EndBorrowInst>(user))
|
||||
continue;
|
||||
|
||||
if (result)
|
||||
return nullptr;
|
||||
|
||||
result = op;
|
||||
}
|
||||
return result ? dyn_cast<PartialApplyInst>(result->getUser()) : nullptr;
|
||||
};
|
||||
|
||||
if (auto *PAI = isOnlyUsedByPartialApply(load)) {
|
||||
if (std::find_if(PAI->use_begin(), PAI->use_end(), [](auto PAIUse) {
|
||||
return isa<AssignByWrapperInst>(PAIUse->getUser()) ||
|
||||
isa<AssignOrInitInst>(PAIUse->getUser());
|
||||
@@ -672,7 +691,6 @@ bool LifetimeChecker::shouldEmitError(const SILInstruction *Inst) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EmittedErrorLocs.push_back(InstLoc);
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user