Skip to content

Fix DiagnoseLifetimeIssues handling of nonescaping arguments. #69184

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/SILOptimizer/Mandatory/DiagnoseLifetimeIssues.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ visitUses(SILValue def, bool updateLivenessAndWeakStores, int callDepth) {
// Try to get information from the called function.
switch (getArgumentState(ai, use, callDepth)) {
case DoesNotEscape:
if (updateLivenessAndWeakStores)
liveness->updateForUse(user, /*lifetimeEnding*/ false);
break;
case CanEscape:
return CanEscape;
Expand Down
39 changes: 39 additions & 0 deletions test/SILOptimizer/diagnose_lifetime_issues.sil
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class WeakCycle {
weak var c: WeakCycle?
}

sil [ossa] @$s24diagnose_lifetime_issues8DelegateCACycfC : $@convention(method) (@thick Delegate.Type) -> @owned Delegate
sil [ossa] @$s24diagnose_lifetime_issues10MyDelegateCACycfC : $@convention(method) (@thick MyDelegate.Type) -> @owned MyDelegate
sil [ossa] @$s24diagnose_lifetime_issues14strongDelegate1dyAA0D0C_tF : $@convention(method) (@guaranteed Delegate, @guaranteed Container) -> ()

Expand Down Expand Up @@ -119,3 +120,41 @@ bb0(%0 : $@thick WeakCycle.Type):
%3 = apply %2(%1) : $@convention(method) (@owned WeakCycle) -> @owned WeakCycle
return %3 : $WeakCycle
}

// Helper
sil private [ossa] @testBorrowInDefer$defer : $@convention(thin) (@guaranteed Delegate) -> () {
bb0(%0 : @closureCapture @guaranteed $Delegate):
debug_value %0 : $Delegate, let, name "delegate", argno 1
fix_lifetime %0 : $Delegate
%8 = tuple ()
return %8 : $()
}

// Test no warning for a value kept alive within a call which does not escape its argument.
sil hidden [ossa] @testBorrowinDefer : $@convention(thin) (@guaranteed Container) -> () {
bb0(%0 : @guaranteed $Container):
debug_value %0 : $Container, let, name "container", argno 1
%2 = metatype $@thick Delegate.Type
// function_ref Delegate.__allocating_init()
%3 = function_ref @$s24diagnose_lifetime_issues8DelegateCACycfC : $@convention(method) (@thick Delegate.Type) -> @owned Delegate

// This is the owned allocation.
%4 = apply %3(%2) : $@convention(method) (@thick Delegate.Type) -> @owned Delegate
%6 = copy_value %4 : $Delegate
%7 = enum $Optional<Delegate>, #Optional.some!enumelt, %6 : $Delegate
%8 = ref_element_addr %0 : $Container, #Container.delegate
%9 = begin_access [modify] [dynamic] %8 : $*@sil_weak Optional<Delegate>

// This is the weak assignment.
store_weak %7 to %9 : $*@sil_weak Optional<Delegate>
destroy_value %7 : $Optional<Delegate>
end_access %9 : $*@sil_weak Optional<Delegate>

// This call keeps the parent alive
%15 = function_ref @testBorrowInDefer$defer : $@convention(thin) (@guaranteed Delegate) -> () // user: %16
%16 = apply %15(%4) : $@convention(thin) (@guaranteed Delegate) -> ()

destroy_value %4 : $Delegate
%18 = tuple ()
return %18 : $()
}