Skip to content

Commit cb205a6

Browse files
committed
[Test] Checked variable lifetimes not extend weak.
Verified that lexical lifetimes DO NOT result in a method call to a weak reference resulting in a strong reference to the object. Consequently, even with lexical lifetimes enabled, it is still possible, within a single scope, for the first method call to an object weakly referenced to occur but for the second such call not to because the object will have been deallocated.
1 parent f48f3ad commit cb205a6

File tree

1 file changed

+48
-14
lines changed

1 file changed

+48
-14
lines changed

validation-test/SILOptimizer/lexical-lifetimes.swift

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
// RUN: %target-run-simple-swift(-Xfrontend -enable-copy-propagation) | %FileCheck %s
1+
// RUN: %target-run-simple-swift(-Xfrontend -disable-availability-checking -parse-as-library -Xfrontend -enable-copy-propagation) | %FileCheck %s
22

3+
// REQUIRES: concurrency
34
// REQUIRES: executable_test
45

56
// =============================================================================
@@ -167,21 +168,54 @@ func test_self_keepsObjectAliveBeyond_callTo_functionTakingClosureCapturingWeakV
167168
Fooer().foo()
168169
}
169170

171+
func do_foo_async(_ work: @escaping () -> ()) -> Task<Void, Never> {
172+
Task {
173+
work()
174+
}
175+
}
176+
class FooerAsync {
177+
var strongSelf: FooerAsync?
178+
__consuming func foo() -> Task<Void, Never> {
179+
weak var weakSelf = self
180+
strongSelf = self
181+
return do_foo_async {
182+
// At this point, strongSelf is keeping the object alive.
183+
weakSelf?.foo1()
184+
// By this point, strongSelf has been nil'd, dropping the object's retain
185+
// count to 0, deallocating the object, so weakSelf is nil.
186+
weakSelf?.foo2()
187+
}
188+
}
189+
func foo1() {
190+
// CHECK: FooerAsync foo1
191+
print(type(of: self), #function)
192+
strongSelf = nil
193+
}
194+
func foo2() {
195+
// CHECK-NOT: FooerAsync foo2
196+
print(type(of: self), #function)
197+
}
198+
}
199+
200+
func test_repeatedLoadWeakSelf() -> Task<Void, Never> {
201+
FooerAsync().foo()
202+
}
203+
170204
// =============================================================================
171205
// = Tests }} =
172206
// =============================================================================
173207

174-
func run() {
175-
test_localLet_keepsObjectAliveBeyondCallToClassWithWeakReference()
176-
// Reenable with rdar://86271875
177-
// test_localVar_keepsObjectAliveBeyondCallToClassWithWeakReference()
178-
test_localLet_keepsObjectAliveBeyondCallToClassWithPointer()
179-
test_localVar_keepsObjectAliveBeyondCallToClassWithPointer()
180-
test_localLet_keepsObjectAliveBeyondCallToSynchronizationPointFunction()
181-
test_localVar_keepsObjectAliveBeyondCallToSynchronizationPointFunction()
182-
183-
test_self_keepsObjectAliveBeyond_callTo_functionTakingClosureCapturingWeakVar()
208+
@main struct Main {
209+
static func main() async {
210+
test_localLet_keepsObjectAliveBeyondCallToClassWithWeakReference()
211+
// Reenable with rdar://86271875
212+
// test_localVar_keepsObjectAliveBeyondCallToClassWithWeakReference()
213+
test_localLet_keepsObjectAliveBeyondCallToClassWithPointer()
214+
test_localVar_keepsObjectAliveBeyondCallToClassWithPointer()
215+
test_localLet_keepsObjectAliveBeyondCallToSynchronizationPointFunction()
216+
test_localVar_keepsObjectAliveBeyondCallToSynchronizationPointFunction()
217+
218+
test_self_keepsObjectAliveBeyond_callTo_functionTakingClosureCapturingWeakVar()
219+
await test_repeatedLoadWeakSelf().value
220+
}
184221
}
185-
186-
run()
187-

0 commit comments

Comments
 (0)