Skip to content

Commit 32a4a67

Browse files
committed
MemoryLifetimeVerifier: fix verification of store_borrow locations
In case of a single-block location, the verification of store_borrow locations didn't work in all cases.
1 parent 9857464 commit 32a4a67

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

lib/SIL/Verifier/MemoryLifetimeVerifier.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ class MemoryLifetimeVerifier {
8989
/// Register the destination address of a store_borrow as borrowed location.
9090
void registerStoreBorrowLocation(SILValue addr);
9191

92+
/// Registers all store_borrow instructions in a block.
93+
void registerStoreBorrowsInBlock(SILBasicBlock *block);
94+
9295
/// Handles locations of the predecessor's terminator, which are only valid
9396
/// in \p block.
9497
/// Example: @out results of try_apply. They are only valid in the
@@ -286,6 +289,13 @@ void MemoryLifetimeVerifier::registerStoreBorrowLocation(SILValue addr) {
286289
}
287290
}
288291

292+
void MemoryLifetimeVerifier::registerStoreBorrowsInBlock(SILBasicBlock *block) {
293+
for (SILInstruction &inst : *block) {
294+
if (auto *sbi = dyn_cast<StoreBorrowInst>(&inst))
295+
registerStoreBorrowLocation(sbi->getDest());
296+
}
297+
}
298+
289299
void MemoryLifetimeVerifier::initDataflow(BitDataflow &dataFlow) {
290300
// Initialize the entry and exit sets to all-bits-set. Except for the function
291301
// entry.
@@ -579,7 +589,6 @@ void MemoryLifetimeVerifier::checkBlock(SILBasicBlock *block, Bits &bits) {
579589
case SILInstructionKind::StoreBorrowInst: {
580590
SILValue destAddr = cast<StoreBorrowInst>(&I)->getDest();
581591
locations.setBits(bits, destAddr);
582-
registerStoreBorrowLocation(destAddr);
583592
break;
584593
}
585594
case SILInstructionKind::CopyAddrInst: {
@@ -764,6 +773,7 @@ void MemoryLifetimeVerifier::verify() {
764773
locations.handleSingleBlockLocations([this](SILBasicBlock *block) {
765774
storeBorrowLocations.clear();
766775
Bits bits(locations.getNumLocations());
776+
registerStoreBorrowsInBlock(block);
767777
checkBlock(block, bits);
768778
});
769779
}

test/SIL/memory_lifetime_failures.sil

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,36 @@ bb0(%0 : @guaranteed $Optional<T>):
361361
return %res : $()
362362
}
363363

364+
// CHECK: SIL memory lifetime failure in @test_store_borrow_single_block: store-borrow location cannot be written
365+
sil [ossa] @test_store_borrow_single_block : $@convention(thin) (@guaranteed T) -> () {
366+
bb0(%0 : @guaranteed $T):
367+
%stk = alloc_stack $T
368+
%copy = copy_value %0 : $T
369+
store %copy to [init] %stk : $*T
370+
%ld = load [take] %stk : $*T
371+
destroy_value %ld : $T
372+
store_borrow %0 to %stk : $*T
373+
dealloc_stack %stk : $*T
374+
%8 = tuple ()
375+
return %8 : $()
376+
}
377+
378+
// CHECK: SIL memory lifetime failure in @test_store_borrow_multi_block: store-borrow location cannot be written
379+
sil [ossa] @test_store_borrow_multi_block : $@convention(thin) (@guaranteed T) -> () {
380+
bb0(%0 : @guaranteed $T):
381+
%stk = alloc_stack $T
382+
%copy = copy_value %0 : $T
383+
store %copy to [init] %stk : $*T
384+
%ld = load [take] %stk : $*T
385+
destroy_value %ld : $T
386+
br bb1
387+
bb1:
388+
store_borrow %0 to %stk : $*T
389+
dealloc_stack %stk : $*T
390+
%8 = tuple ()
391+
return %8 : $()
392+
}
393+
364394
// CHECK: SIL memory lifetime failure in @test_cast_br_take_always: memory is not initialized, but should be
365395
sil [ossa] @test_cast_br_take_always : $@convention(thin) <U, V> (@in U) -> () {
366396
bb0(%0 : $*U):

0 commit comments

Comments
 (0)