Skip to content

Commit 863604e

Browse files
committed
SIL: Fix MemoryLifetimeVerifier for try_apply with indirect error result
1 parent 05ccd97 commit 863604e

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

include/swift/SIL/ApplySite.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,14 @@ class FullApplySite : public ApplySite {
741741
&& (getCalleeArgIndex(op) < getNumIndirectSILResults());
742742
}
743743

744+
/// Returns true if \p op is an operand that passes an indirect
745+
/// result argument to the apply site.
746+
bool isIndirectErrorResultOperand(const Operand &op) const {
747+
return isArgumentOperand(op)
748+
&& (getCalleeArgIndex(op) >= getNumIndirectSILResults())
749+
&& (getCalleeArgIndex(op) < getNumIndirectSILErrorResults());
750+
}
751+
744752
static FullApplySite getFromOpaqueValue(void *p) { return FullApplySite(p); }
745753

746754
static bool classof(const SILInstruction *inst) {

lib/SIL/Verifier/MemoryLifetimeVerifier.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -490,16 +490,24 @@ void MemoryLifetimeVerifier::setBitsOfPredecessor(Bits &getSet, Bits &killSet,
490490

491491
TermInst *term = pred->getTerminator();
492492
if (auto *tai = dyn_cast<TryApplyInst>(term)) {
493-
// @out results of try_apply are only valid in the normal-block, but not in
494-
// the throw-block.
495-
if (tai->getNormalBB() != block)
496-
return;
497-
498493
FullApplySite FAS(tai);
499-
for (Operand &op : tai->getAllOperands()) {
500-
if (FAS.isArgumentOperand(op) &&
501-
FAS.getArgumentConvention(op) == SILArgumentConvention::Indirect_Out) {
502-
locations.genBits(getSet, killSet, op.get());
494+
495+
if (block == tai->getNormalBB()) {
496+
// @out results of try_apply are only valid in the normal-block.
497+
for (Operand &op : tai->getAllOperands()) {
498+
if (FAS.isArgumentOperand(op) &&
499+
FAS.isIndirectResultOperand(op)) {
500+
locations.genBits(getSet, killSet, op.get());
501+
}
502+
}
503+
} else {
504+
// @error_indirect results of try_apply are only valid in the error-block.
505+
assert(block == tai->getErrorBB());
506+
for (Operand &op : tai->getAllOperands()) {
507+
if (FAS.isArgumentOperand(op) &&
508+
FAS.isIndirectErrorResultOperand(op)) {
509+
locations.genBits(getSet, killSet, op.get());
510+
}
503511
}
504512
}
505513
} else if (auto *castInst = dyn_cast<CheckedCastAddrBranchInst>(term)) {

0 commit comments

Comments
 (0)