Skip to content

Commit d9fdce5

Browse files
committed
[ownership] When computing usesNotContainedWithinLifetime make sure the error is only a use not in lifetime error.
Otherwise, we can return true in cases where we do not have a proper linear lifetime which can occur in the presence of destructures. <rdar://problem/67698939>
1 parent 61e93c5 commit d9fdce5

File tree

2 files changed

+96
-3
lines changed

2 files changed

+96
-3
lines changed

lib/SIL/Verifier/LinearLifetimeChecker.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,6 @@ bool LinearLifetimeChecker::validateLifetime(
682682
bool LinearLifetimeChecker::usesNotContainedWithinLifetime(
683683
SILValue value, ArrayRef<Operand *> consumingUses,
684684
ArrayRef<Operand *> usesToTest) {
685-
686685
auto errorBehavior = ErrorBehaviorKind(
687686
ErrorBehaviorKind::ReturnFalse |
688687
ErrorBehaviorKind::StoreNonConsumingUsesOutsideLifetime);
@@ -707,7 +706,13 @@ bool LinearLifetimeChecker::usesNotContainedWithinLifetime(
707706
assert(numFoundUses == uniqueUsers.size());
708707
#endif
709708

710-
// Return true if we /did/ found an error and when emitting that error, we
709+
// If we found any error except for uses outside of our lifetime, bail.
710+
if (error.getFoundLeak() || error.getFoundOverConsume() ||
711+
error.getFoundUseAfterFree())
712+
return false;
713+
714+
// Return true if we /did/ find an error and when emitting that error, we
711715
// found /all/ uses we were looking for.
712-
return error.getFoundError() && numFoundUses == usesToTest.size();
716+
return error.getFoundUseOutsideOfLifetime() &&
717+
numFoundUses == usesToTest.size();
713718
}

test/SILOptimizer/semantic-arc-opts.sil

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,19 @@ sil @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) ->
2020
sil @owned_user : $@convention(thin) (@owned Builtin.NativeObject) -> ()
2121
sil @get_owned_obj : $@convention(thin) () -> @owned Builtin.NativeObject
2222
sil @unreachable_guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> MyNever
23+
sil @inout_user : $@convention(thin) (@inout FakeOptional<NativeObjectPair>) -> ()
2324

2425
struct NativeObjectPair {
2526
var obj1 : Builtin.NativeObject
2627
var obj2 : Builtin.NativeObject
2728
}
2829

30+
struct FakeOptionalNativeObjectPairPair {
31+
var pair1 : FakeOptional<NativeObjectPair>
32+
var pair2 : FakeOptional<NativeObjectPair>
33+
}
34+
sil @inout_user2 : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> ()
35+
2936
sil @get_nativeobject_pair : $@convention(thin) () -> @owned NativeObjectPair
3037

3138
protocol MyFakeAnyObject : Klass {
@@ -2639,3 +2646,84 @@ bb6:
26392646
inject_enum_addr %0 : $*FakeOptional<Klass>, #FakeOptional.none!enumelt
26402647
br bb5
26412648
}
2649+
2650+
// CHECK-LABEL: sil [ossa] @destructure_with_differing_lifetimes_inout_1 : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> () {
2651+
// CHECK-NOT: load_borrow
2652+
// CHECK: } // end sil function 'destructure_with_differing_lifetimes_inout_1'
2653+
sil [ossa] @destructure_with_differing_lifetimes_inout_1 : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> () {
2654+
bb0(%0 : $*FakeOptionalNativeObjectPairPair):
2655+
%0a = struct_element_addr %0 : $*FakeOptionalNativeObjectPairPair, #FakeOptionalNativeObjectPairPair.pair1
2656+
%1 = load [copy] %0a : $*FakeOptional<NativeObjectPair>
2657+
switch_enum %1 : $FakeOptional<NativeObjectPair>, case #FakeOptional.some!enumelt: bb1, default bb2
2658+
2659+
bb2(%2 : @owned $FakeOptional<NativeObjectPair>):
2660+
destroy_value %2 : $FakeOptional<NativeObjectPair>
2661+
br bbEnd
2662+
2663+
bb1(%3 : @owned $NativeObjectPair):
2664+
(%3a, %3b) = destructure_struct %3 : $NativeObjectPair
2665+
cond_br undef, bb1a, bb1b
2666+
2667+
bb1a:
2668+
destroy_value %3a : $Builtin.NativeObject
2669+
destroy_value %3b : $Builtin.NativeObject
2670+
br bbEnd
2671+
2672+
bb1b:
2673+
destroy_value %3a : $Builtin.NativeObject
2674+
%f = function_ref @inout_user2 : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> ()
2675+
apply %f(%0) : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> ()
2676+
destroy_value %3b : $Builtin.NativeObject
2677+
br bbEnd
2678+
2679+
bbEnd:
2680+
%9999 = tuple()
2681+
return %9999 : $()
2682+
}
2683+
2684+
// CHECK-LABEL: sil [ossa] @destructure_with_differing_lifetimes_inout_2 : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> () {
2685+
// CHECK-NOT: load_borrow
2686+
// CHECK: } // end sil function 'destructure_with_differing_lifetimes_inout_2'
2687+
sil [ossa] @destructure_with_differing_lifetimes_inout_2 : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> () {
2688+
bb0(%0 : $*FakeOptionalNativeObjectPairPair):
2689+
%0a = struct_element_addr %0 : $*FakeOptionalNativeObjectPairPair, #FakeOptionalNativeObjectPairPair.pair1
2690+
%1 = load [copy] %0a : $*FakeOptional<NativeObjectPair>
2691+
switch_enum %1 : $FakeOptional<NativeObjectPair>, case #FakeOptional.some!enumelt: bb1, default bb2
2692+
2693+
bb2(%2 : @owned $FakeOptional<NativeObjectPair>):
2694+
destroy_value %2 : $FakeOptional<NativeObjectPair>
2695+
br bbEnd
2696+
2697+
bb1(%3 : @owned $NativeObjectPair):
2698+
(%3a, %3b) = destructure_struct %3 : $NativeObjectPair
2699+
cond_br undef, bb1a, bb1b
2700+
2701+
bb1a:
2702+
destroy_value %3a : $Builtin.NativeObject
2703+
br bb1ab
2704+
2705+
bb1ab:
2706+
destroy_value %3b : $Builtin.NativeObject
2707+
br bbEnd
2708+
2709+
bb1b:
2710+
destroy_value %3a : $Builtin.NativeObject
2711+
%f = function_ref @inout_user2 : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> ()
2712+
apply %f(%0) : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> ()
2713+
cond_br undef, bb1ba, bb1bb
2714+
2715+
bb1ba:
2716+
br bb1baEnd
2717+
2718+
bb1bb:
2719+
br bb1baEnd
2720+
2721+
bb1baEnd:
2722+
destroy_value %3b : $Builtin.NativeObject
2723+
br bbEnd
2724+
2725+
bbEnd:
2726+
%9999 = tuple()
2727+
return %9999 : $()
2728+
}
2729+

0 commit comments

Comments
 (0)