Navigation Menu

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-613] Arc misbehaviour in class-only protocol composition #43230

Closed
swift-ci opened this issue Jan 25, 2016 · 7 comments
Closed

[SR-613] Arc misbehaviour in class-only protocol composition #43230

swift-ci opened this issue Jan 25, 2016 · 7 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself crash Bug: A crash, i.e., an abnormal termination of software run-time crash Bug → crash: Swift code crashed during execution

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-613
Radar rdar://problem/24334702
Original Reporter Nick Carella (JIRA User)
Type Bug
Status Resolved
Resolution Done
Environment

Xcode: Version 7.2 (7C68)

Additional Detail from JIRA
Votes 2
Component/s Compiler
Labels Bug, RunTimeCrash
Assignee None
Priority Medium

md5: df539b1912bca95d03d50bac3b761556

Issue Description:

Object will be deallocated after capturing its function

import Foundation

protocol TestAny {
    func testAny()
}

protocol TestRef: class, TestAny {
    func testRef()
}

class Test: TestRef {

    func testAny() {
        print("any")
    }

    func testRef() {
        print("ref")
    }
}

let test: protocol<TestRef>? = Test()

if let t = test?.testAny {}

test?.testAny() // crash
@belkadan
Copy link
Contributor

@atrick, is this the thing you just fixed?

@atrick
Copy link
Member

atrick commented Jan 25, 2016

I'm afraid this is not something I fixed.

In this code:

func foo(test: TestRef?) {
if let t = test?.testAny {}
}

A function-type value is being returned from test?.testAny without any partial_apply or retain:

// function_ref main.TestAny.testAny <A where A: main.TestAny> (A) -> () -> ()
%11 = function_ref @TFP4main7TestAny7testAnyuRq_S0Fq_FT_T : $@convention(thin) <τ_0_0 where τ_0_0 : TestAny> (@in τ_0_0) -> @owned @callee_owned () -> () // user: %12
%12 = apply %11<@opened("0844AB78-C38F-11E5-A516-AC87A3215592") TestRef>(%9#1) : $@convention(thin) <τ_0_0 where τ_0_0 : TestAny> (@in τ_0_0) -> @owned @callee_owned () -> () // user: %15

Then a closure is being created via partial_apply from the function value:

// function_ref reabstraction thunk helper from @callee_owned () -> (@unowned ()) to @callee_owned (@in ()) -> (@out ())
%14 = function_ref @TTRXFodTXFo_iTiT_ : $@convention(thin) (@out (), @in (), @owned @callee_owned () -> ()) -> () // user: %15
%15 = partial_apply %14(%12) : $@convention(thin) (@out (), @in (), @owned @callee_owned () -> ()) -> () // user: %16

That closure is wrapped in an Optional:

%16 = enum $Optional&lt;() -&gt; ()&gt;, #Optional.Some!enumelt.1, %15 : $@callee_owned (@out (), @in ()) -> () // user: %18

Then another closure is created

bb4(%22 : $@callee_owned (@out (), @in ()) -> ()): // Preds: bb2
// function_ref reabstraction thunk helper from @callee_owned (@in ()) -> (@out ()) to @callee_owned () -> (@unowned ())
%23 = function_ref @TTRXFo_iTiTXFodT_ : $@convention(thin) (@owned @callee_owned (@out (), @in ()) -> ()) -> () // user: %24
%24 = partial_apply %23(%22) : $@convention(thin) (@owned @callee_owned (@out (), @in ()) -> ()) -> () // users: %25, %26

Then we release the dead closure which has closed over the test? reference...

strong_release %24 : $@callee_owned () -> () // id: %26

It may be that one of these closure/thunk calls is failing to retain the closed-over self. At any rate, when I enable optimization, the dead closure disappears and the crash goes away.

@swift-ci
Copy link
Collaborator Author

Comment by Nikita Ilyasov (JIRA)

It also can be reproduced like this:

let test: protocol<TestRef> = Test()

func take_block(block: () -> ()) {
    block();
}

take_block(test.testAny)

test.testAny()

but not like this:

take_block(test.testRef)

@swift-ci
Copy link
Collaborator Author

Comment by Nikita Ilyasov (JIRA)

It can be reproduced in Release build configuration, it's not `NotOptimizedOnly`

@belkadan
Copy link
Contributor

Ah, okay. I guess it was just that particular test case where it got optimized away. Label removed.

@jckarter
Copy link
Member

Testing a fix: #2316

@jckarter
Copy link
Member

Fix merged as 461c8e7.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@AnthonyLatsis AnthonyLatsis added the crash Bug: A crash, i.e., an abnormal termination of software label Dec 12, 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 crash Bug: A crash, i.e., an abnormal termination of software run-time crash Bug → crash: Swift code crashed during execution
Projects
None yet
Development

No branches or pull requests

5 participants