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-8074] EXC_BAD_ACCESS with curried mutating instance method. #50607

Closed
swift-ci opened this issue Jun 22, 2018 · 10 comments
Closed

[SR-8074] EXC_BAD_ACCESS with curried mutating instance method. #50607

swift-ci opened this issue Jun 22, 2018 · 10 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

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-8074
Radar rdar://problem/41361334
Original Reporter Vatsal Manot (JIRA User)
Type Bug
Status Resolved
Resolution Done
Environment

Swift 4.2, Xcode 10 beta 1.

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, CompilerCrash
Assignee Vatsal Manot (JIRA)
Priority Medium

md5: e929ac025b57a3a6742eb1cd9eb3303c

Issue Description:

The following crashes with EXC_BAD_ACCESS. The addition of `foo` seems to be the cause.

struct X
{
    var foo = NSObject()
    var val = 1
    
    mutating func add(_ int: Int)
    {
        foo = int as NSNumber
        val += int
    }
}

var x = X()
var add = X.add
add(&x)(1) // EXC_BAD_ACCESS
@slavapestov
Copy link
Member

The SIL for the X.add curry thunk is wrong – there's a spurious `copy_addr` in there:

  // function_ref X.add(_:)
  %1 = function_ref @$S2xx1XV3addyySiF : $@convention(method) (Int, @inout X) -> () // user: %4
  %2 = alloc_stack $X                             // users: %5, %4, %3
  copy_addr %0 to [initialization] %2 : $*X       // id: %3
  %4 = partial_apply [callee_guaranteed] %1(%2) : $@convention(method) (Int, @inout X) -> () // user: %6
  dealloc_stack %2 : $*X                          // id: %5
  return %4 : $@callee_guaranteed (Int) -> ()     // id: %6

I think this is a regression from the +0 arguments work.

@swift-ci
Copy link
Collaborator Author

Comment by Vatsal Manot (JIRA)

@slavapestov is there a workaround for this? I've been using this in a generic context:

@inlinable public func build<T, U, V>(_ x: T, with f: ((inout T) throws -> ((U) -> V)), _ y: U) rethrows -> T
{
    var x = x
    
    _ =  try f(&x)(y)
    
    return x
}

@slavapestov
Copy link
Member

So using an unbound method reference like X.add in this case is not a good idea if the method is mutating, because you get undefined behavior if the method reference is allowed to escape.

In this example, you're immediately applying it twice, so we could make it work again.

As a workaround, just write an explicit closure instead of referencing X.add.

@slavapestov
Copy link
Member

You can change build() to take a (inout T, U) throws -> V instead of a ((inout T) throws -> ((U) -> V)), and then pass in { $0.add($1) } instead of X.add.

@swift-ci
Copy link
Collaborator Author

Comment by Vatsal Manot (JIRA)

@slavapestov I've been using this to shorten:

var x = self
x.mutatingFunc()
return x

... in about 78 callsites.

@swift-ci
Copy link
Collaborator Author

Comment by Vatsal Manot (JIRA)

Ah... I see. Thank you for the prompt response!

@slavapestov
Copy link
Member

@swift-ci create

@jckarter
Copy link
Member

I don’t think we can reasonably make this work at all with inout exclusivity enforcement, so we’re going to have to break compatibility here. At one point we had code that banned partial application of mutating methods, but that must have either broke, or there’s a loophole. We should figure out why it isn’t getting diagnosed.

@jckarter
Copy link
Member

Here's a patch that warns in this case (upgraded to an error in Swift 5 mode): #17642

@jckarter
Copy link
Member

jckarter commented Jul 2, 2018

Merged. You should get a warning now that this isn't really supported.

@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
Projects
None yet
Development

No branches or pull requests

4 participants