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-11906] Private methods of an open class are exposed to another framework extending this class #54323

Closed
swift-ci opened this issue Dec 5, 2019 · 5 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Dec 5, 2019

Previous ID SR-11906
Radar rdar://problem/57712089
Original Reporter wernera77 (JIRA User)
Type Bug
Status Closed
Resolution Done

Attachment: Download

Environment

Xcode 11.2.1, Swift 5.1.2

Additional Detail from JIRA
Votes 2
Component/s Compiler
Labels Bug
Assignee @aschwaighofer
Priority Medium

md5: 53dfcb5053681526ac625a63f033a5a4

Issue Description:

We work with a lot of dynamic Swift frameworks and ran into the following scenario:

Framework1:

open class Ape {
    public init() {}

    public func foo() {
    }

    private func bar() {
    }
}

Framework2:

import Framework1

public final class Gorilla: Ape {
    public override init() {
        super.init()
        foo()
    }
}

Framework2 links to Framework1.

Now if we inspect the symbols present in Framework2 (by using `nm`) we find that the private func `bar()` is present.

This gives us big issues because we cannot rely on semantic versioning with prebuilt frameworks because of this (we use binary caches per swift version). To make this more clear:

Say we compile Framework2 with Framework1 version 1.1 which added some public methods and adds a private method (say `bar()`) in an open class.
However: Framework2 only requires version 1.0 of the Framework1 API and receives Framework1 version 1.0 at runtime.

=> A crash will occur at runtime because the added private method (which was introduced in 1.1) is not available.

@beccadax
Copy link
Contributor

beccadax commented Dec 6, 2019

@swift-ci create

@aschwaighofer
Copy link
Member

Did you use the Xcode build setting "build libraries for distribution" or alternatively did you use the command line flag -enable-library-evolution?

Otherwise, it is expected that you run into issues like the one you mention.

https://developer.apple.com/videos/play/wwdc2019/416/

@swift-ci
Copy link
Collaborator Author

Comment by Werner Altewischer (JIRA)

I just tried that, however even when building both frameworks with "BUILD_LIBRARY_FOR_DISTRIBUTION=YES" there are still private symbols present in the undefined symbols of Framework2.

e.g.

private symbol Framework1.x is listed in the output of `nm -u Framework2.framework/Framework2`

@aschwaighofer
Copy link
Member

Something has gone wrong with the build settings then.

I have attached the example LibraryEvolution.zip.

If you open and build the UseSwiftFramework.xcodeproj project and list the symbols in UseSwiftFramework.framework there should not be a mention of the symbol bar.

@swift-ci
Copy link
Collaborator Author

Comment by Werner Altewischer (JIRA)

I see my mistake, I enabled the BUILD_LIBRARY_FOR_DISTRIBUTION only for Release mode. It does seem to work now, thanks.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself
Projects
None yet
Development

No branches or pull requests

3 participants