Skip to content
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

[SR-14147] Diagnose suspicious weak references #56526

Open
atrick opened this issue Feb 3, 2021 · 0 comments
Open

[SR-14147] Diagnose suspicious weak references #56526

atrick opened this issue Feb 3, 2021 · 0 comments
Labels
compiler The Swift compiler in itself diagnostics QoI Bug: Diagnostics Quality of Implementation new feature

Comments

@atrick
Copy link
Member

atrick commented Feb 3, 2021

Previous ID SR-14147
Radar rdar://73910632
Original Reporter @atrick
Type New Feature
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels New Feature, DiagnosticsQoI
Assignee None
Priority Medium

md5: 398ecfadf7364a380cdee5741d5efa1b

Issue Description:

Issue a compiler warning when assigning an object to a weak references that will likely be destroyed before the weak reference is used.

The simple but common case should be easy to diagnose:

 let delegate = Delegate()
 container.delegate = delegate
 // delegate is destroyed here at -O
 container.callDelegate()

Weak reference are often used to capture closure arguments, so that needs to be handled as well.

This pattern can generally be recogized as:

  • a locally allocated object 'alloc_ref'

  • assignment to a weak property or box (for a closure) 'store_weak'

  • use of the property's parent object

  • no subsequent use of the local object

However, this pattern won't catch uses involving asynchronous execution:

We also should try to diagnose this pattern...

import Dispatch
class SomeDispatcher {
  func runBackground(completionHandler: ()->()) { completionHandler() }
}
func foo() {
  let semaphore = DispatchSemaphore(value: 0)
  let dispatcher = SomeDispatcher()
  dispatcher.runBackground(completionHandler: { [weak dispatcher] in
      // This dispatcher check may be hidden within "runBackground".
      // The compiler won't necessarily see it.
      if let dispatcher = dispatcher {
          _ = dispatcher
          semaphore.signal()
      }
  })
  // 'dispatcher' will be destroyed here, before checking the semaphore unless
  // its lifetime is extended.
  semaphore.wait()
}

Here, 'dispatcher' is used (as self) in the same call that captures the weak reference. So the "no subsequent use" rule above does not apply here. The compiler would need to know that 'runBackground' is asynchronous.

Should we simply warn about any weak reference to a local variable passed to an asynchronous routine?

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler The Swift compiler in itself diagnostics QoI Bug: Diagnostics Quality of Implementation new feature
Projects
None yet
Development

No branches or pull requests

1 participant