From 135d62007a3c099820cbc0256bd2bc769ee85334 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Fri, 13 Oct 2023 20:54:30 -0700 Subject: [PATCH] Fix DiagnoseLifetimeIssues handling of nonescaping arguments. Function call arguments were not being treated as liveness uses. Unblocks SIL: Treat store_borrow as borrowing its source, and have the move-only checker account for borrow scopes. #69169 https://github.com/apple/swift/pull/69169 --- .../Mandatory/DiagnoseLifetimeIssues.cpp | 2 + .../SILOptimizer/diagnose_lifetime_issues.sil | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/lib/SILOptimizer/Mandatory/DiagnoseLifetimeIssues.cpp b/lib/SILOptimizer/Mandatory/DiagnoseLifetimeIssues.cpp index 91b8b8b711337..0f4c42e49371e 100644 --- a/lib/SILOptimizer/Mandatory/DiagnoseLifetimeIssues.cpp +++ b/lib/SILOptimizer/Mandatory/DiagnoseLifetimeIssues.cpp @@ -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; diff --git a/test/SILOptimizer/diagnose_lifetime_issues.sil b/test/SILOptimizer/diagnose_lifetime_issues.sil index 8523b9d78353f..5a75d7112f4cd 100644 --- a/test/SILOptimizer/diagnose_lifetime_issues.sil +++ b/test/SILOptimizer/diagnose_lifetime_issues.sil @@ -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) -> () @@ -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, #Optional.some!enumelt, %6 : $Delegate + %8 = ref_element_addr %0 : $Container, #Container.delegate + %9 = begin_access [modify] [dynamic] %8 : $*@sil_weak Optional + + // This is the weak assignment. + store_weak %7 to %9 : $*@sil_weak Optional + destroy_value %7 : $Optional + end_access %9 : $*@sil_weak Optional + + // 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 : $() +}