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-7717] Compiler SegFaults when weak reference is captured in a closure from another closure with a strong reference #50257

Closed
swift-ci opened this issue May 17, 2018 · 1 comment
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

Previous ID SR-7717
Radar None
Original Reporter V-FEXrt (JIRA User)
Type Bug
Status Resolved
Resolution Duplicate

Attachment: Download

Environment

MacBook Pro (15-inch, 2016)

Processor 2.7 GHz Intel Core i7

Memory 16 GB 2133 Mhz LPDDR3

Graphics Intel HD Graphics 530 1536 MB


macOS High Sierra Version 10.13.4

Xcode Version 9.3.1 (9E501)

Apple Swift version 4.1 (swiftlang-902.0.48 clang-902.0.37.1)
Target: x86_64-apple-darwin17.5.0

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug
Assignee None
Priority Medium

md5: 0946fdc0953896146e8c4b40ed02a5f9

duplicates:

  • SR-3186 Crash when capture list references parameter of outer single-expression closure

Issue Description:

This is somewhat difficult to explain with words, so please see the code below. The function bar causes the compile to seg fault with the following error:

"Command failed due to signal: Segmentation fault: 11"

See the attached xcode project for a working minimal example.

class Other {
    static func acceptsClosure(closure: () -> Void) {
        closure()
    }
}

class Foo {
    var start = 0
    let end = 10

    func bar() { // Function causes compiler to Seg Fault
        let closure = call(on: self) { (me) in
            Other.acceptsClosure { [weak me] in
                me?.start = me?.end ?? 0
            }
        }

        closure()
    }

    func buzz() { // Function doesn't Seg Fault, but requires _ = me
        let closure = call(on: self) { (me) in
            _ = me
            Other.acceptsClosure { [weak me] in
                me?.start = me?.end ?? 0
            }
        }

        closure()
    }

    func bat() { // Function doesn't Seg Fault, but retains a strong reference to Foo
        let closure = call(on: self) { (me) in
            Other.acceptsClosure {
                me.start = me.end
            }
        }

        closure()
    }

    // Convenience function: Capture weak reference, convert to strong at call time
    func call<T: AnyObject>(on: T, closure: @escaping (T) -> Void) -> (() -> Void) {
        return { [weak on] in
            guard let on = on else { return }
            closure(on)
        }
    }
}
@swift-ci
Copy link
Collaborator Author

Comment by Elliott Williams (JIRA)

I've been able to reproduce this. Interestingly, if I explicitly declare the type of the strong referenced variable, the segfault goes away. Modifying your example fixes the segfault:

func bar() {
    let closure = call(on: self) { (me: Foo) in    // explicitly declare type of `me`
        Other.acceptsClosure { [weak me] in
            me?.start = me?.end ?? 0
        }
    }

    closure()
}

Environment:

macOS High Sierra 10.13.4 (17E202)
Apple Swift version 4.1 (swiftlang-902.0.48 clang-902.0.37.1)
Target: x86_64-apple-darwin17.5.0

@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

1 participant