Skip to content

Commit 4d77b82

Browse files
committed
Update store_borrow verification in MemoryLifetimeVerifier
- Ensure there are no double end_borrows - Ensure there are no end_borrows after dealloc_stack of the dest
1 parent e5d2475 commit 4d77b82

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

lib/SIL/Verifier/MemoryLifetimeVerifier.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,13 @@ void MemoryLifetimeVerifier::initDataflowInBlock(SILBasicBlock *block,
377377
}
378378
break;
379379
}
380+
case SILInstructionKind::EndBorrowInst: {
381+
auto *ebi = cast<EndBorrowInst>(&I);
382+
if (auto *sbi = dyn_cast<StoreBorrowInst>(ebi->getOperand())) {
383+
killBits(state, sbi->getDest());
384+
}
385+
break;
386+
}
380387
case SILInstructionKind::DestroyAddrInst:
381388
case SILInstructionKind::DeallocStackInst:
382389
killBits(state, I.getOperand(0));
@@ -696,8 +703,13 @@ void MemoryLifetimeVerifier::checkBlock(SILBasicBlock *block, Bits &bits) {
696703
break;
697704
}
698705
case SILInstructionKind::EndBorrowInst: {
699-
if (SILValue orig = cast<EndBorrowInst>(&I)->getSingleOriginalValue())
700-
requireBitsSet(bits, orig, &I);
706+
auto *ebi = cast<EndBorrowInst>(&I);
707+
if (auto *sbi = dyn_cast<StoreBorrowInst>(ebi->getOperand())) {
708+
requireBitsSet(bits, sbi->getDest(), &I);
709+
locations.clearBits(bits, sbi->getDest());
710+
} else if (auto *lbi = dyn_cast<LoadBorrowInst>(ebi->getOperand())) {
711+
requireBitsSet(bits, lbi->getOperand(), &I);
712+
}
701713
break;
702714
}
703715
case SILInstructionKind::UncheckedRefCastAddrInst:
@@ -779,11 +791,7 @@ void MemoryLifetimeVerifier::checkBlock(SILBasicBlock *block, Bits &bits) {
779791
}
780792
case SILInstructionKind::DeallocStackInst: {
781793
SILValue opVal = cast<DeallocStackInst>(&I)->getOperand();
782-
if (isStoreBorrowLocation(opVal)) {
783-
requireBitsSet(bits, opVal, &I);
784-
} else {
785-
requireBitsClear(bits & nonTrivialLocations, opVal, &I);
786-
}
794+
requireBitsClear(bits & nonTrivialLocations, opVal, &I);
787795
// Needed to clear any bits of trivial locations (which are not required
788796
// to be zero).
789797
locations.clearBits(bits, opVal);

test/SIL/memory_lifetime_failures.sil

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,17 @@ bb0(%0 : @guaranteed $Optional<T>):
373373
return %res : $()
374374
}
375375

376+
// CHECK: SIL memory lifetime failure in @test_store_borrow_addr_after_dealloc: memory is initialized, but shouldn't be
377+
sil [ossa] @test_store_borrow_addr_after_dealloc : $@convention(thin) (@guaranteed Optional<T>) -> () {
378+
bb0(%0 : @guaranteed $Optional<T>):
379+
%s = alloc_stack $Optional<T>
380+
%sb = store_borrow %0 to %s : $*Optional<T>
381+
dealloc_stack %s : $*Optional<T>
382+
end_borrow %sb : $*Optional<T>
383+
%res = tuple ()
384+
return %res : $()
385+
}
386+
376387
// CHECK: SIL memory lifetime failure in @test_cast_br_take_always: memory is not initialized, but should be
377388
sil [ossa] @test_cast_br_take_always : $@convention(thin) <U, V> (@in U) -> () {
378389
bb0(%0 : $*U):

0 commit comments

Comments
 (0)