Skip to content

Commit 6a01bf4

Browse files
committed
[LifetimeCompletion] Don't destroy alloc_boxes.
A destroy_value of an alloc_box unconditionally destroys the value within the box. On unreachable paths, such memory may not be initialized, so it cannot be destroyed unconditionally. Moreover, destroying values stored in memory is outside the purview of OSSA lifetime completion.
1 parent 5881ea4 commit 6a01bf4

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

lib/SIL/Utils/OSSALifetimeCompletion.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ static SILInstruction *endOSSALifetime(SILValue value, SILBuilder &builder) {
6262
auto loc =
6363
RegularLocation::getAutoGeneratedLocation(builder.getInsertionPointLoc());
6464
if (value->getOwnershipKind() == OwnershipKind::Owned) {
65+
if (value->getType().is<SILBoxType>()) {
66+
return builder.createDeallocBox(loc, value);
67+
}
6568
return builder.createDestroyValue(loc, value);
6669
}
6770
return builder.createEndBorrow(loc, value);

test/SILOptimizer/ossa_lifetime_completion.sil

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ indirect enum IndirectEnumNontrivialPayload {
445445
// CHECK: cond_br undef, {{bb[0-9]+}}, [[BASIC_BLOCK4:bb[0-9]+]]
446446
// CHECK: [[BASIC_BLOCK4]]:
447447
// CHECK: end_borrow [[C]]
448-
// CHECK: destroy_value [[BOX]]
448+
// CHECK: dealloc_box [[BOX]]
449449
// CHECK: unreachable
450450
// CHECK-LABEL: } // end sil function 'project_box_owned'
451451
sil [ossa] @project_box_owned : $@convention(thin) (@owned IndirectEnumNontrivialPayload) -> () {
@@ -498,3 +498,18 @@ bb0:
498498
dealloc_stack %result_addr : $*()
499499
return %retval : $()
500500
}
501+
502+
// CHECK-LABEL: begin running test {{.*}} on alloc_box: ossa-lifetime-completion
503+
// CHECK-LABEL: sil [ossa] @alloc_box : {{.*}} {
504+
// CHECK: [[BOX:%[^,]+]] = alloc_box
505+
// CHECK: dealloc_box [[BOX]]
506+
// CHECK-LABEL: } // end sil function 'alloc_box'
507+
// CHECK-LABEL: end running test {{.*}} on alloc_box: ossa-lifetime-completion
508+
sil [ossa] @alloc_box : $@convention(thin) (@owned C) -> () {
509+
entry(%instance : @owned $C):
510+
%box = alloc_box ${ var C }
511+
specify_test "ossa-lifetime-completion %box"
512+
%addr = project_box %box : ${ var C }, 0
513+
store %instance to [init] %addr : $*C
514+
unreachable
515+
}

test/SILOptimizer/silgen_cleanup_complete_ossa.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ sil @unreachableHandler : $@convention(thin) () -> ()
3838
// CHECK: bb2:
3939
// CHECK: apply
4040
// CHECK: end_borrow [[BORROW]] : ${ var FakeOptional<Klass> }
41-
// CHECK: destroy_value [[BOX]] : ${ var FakeOptional<Klass> }
41+
// CHECK: dealloc_box [[BOX]] : ${ var FakeOptional<Klass> }
4242
// CHECK: unreachable
4343
sil [ossa] @testCompleteOSSALifetimes : $@convention(thin) (@owned FakeOptional<Klass>) -> () {
4444
bb0(%0 : @owned $FakeOptional<Klass>):

0 commit comments

Comments
 (0)