Skip to content

Fix bad interaction between SIL deserialization and weak linking [5.1 08/28] #27104

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

Conversation

slavapestov
Copy link
Contributor

  • Description: When using conditionally-available framework declarations from a client app, we're supposed to weak link those declarations. However if the reference came from deserialized SIL code, eg if the client calls a function in the framework that has a default argument, then that reference was not weak linked. This is because SIL functions only stored a single 'weak linked' bit that was computed from the deployment target of the framework together with the declaration's availability. But instead we need to store the version range in the SIL function and make the determination based on the deployment target of the client into which the SIL function is deserialized.

  • Scope of the issue: This affects anyone that's writing an app that deploys to OS version N, but takes advantage of a Swift-only framework that's available in version N+1.

  • Origination: The problem has been there ever since weak linking was introduced in Swift 5.0.

  • Risk: It's a big change, so medium, but mostly it's a straightforward change.

  • Reviewed by: @jrose-apple

  • Radar: rdar://problem/52783668

First, remove the AvailabilityContext parameter; it was confusing because
we actually always want to use the deployment target here.

Then, split this method up into three methods:

- isAlwaysWeakImported(): simply checks for a @_weakLinked attribute, either
  on the declaration itself or one of its parent contexts.

- getAvailabilityForLinkage(): returns the OS version availability when
  this declaration was introduced, or if the declaration does not have
  explicit availability, check it's storage (if its an accessor), or its
  parent contexts.

- isWeakImported(ModuleDecl *fromModule): combines these two checks to
  determine if the declaration should be weak linked when referenced from
  the given module, or if it might be weak referenced from some module
  (if the module parameter is null).
…ported flag

The weak imported flag is now only set if the attribute is unconditionally
weak linked, which is the case when it or one of its parent contexts has a
@_weakLinked attribute.

To correctly handle weak linking based availability with serialized SIL
functions, we need to serialize the actual version tuple when the SIL function
was introduced. This is because the deployment target of the client app can
be older than the deployment target that the original module was built with.

Fixes <rdar://problem/52783668>.
@slavapestov slavapestov requested a review from a team as a code owner September 10, 2019 17:28
@slavapestov
Copy link
Contributor Author

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 80aae9e

@slavapestov
Copy link
Contributor Author

@dcci @shahmishal Is this a known failure on this branch? Looks unrelated to my PR:

14:46:19 Testing Time: 32.56s
14:46:19 ********************
14:46:19 Unresolved Tests (1):
14:46:19     lldb-Suite :: lang/swift/enum_objc/TestEnumObjC.py

@slavapestov
Copy link
Contributor Author

@swift-ci Please test Linux

@slavapestov slavapestov merged commit d672733 into swiftlang:swift-5.1-branch-08-28-2019 Sep 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants