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-2755] False objc_autoreleaseReturnValue dependency building on Linux #45359
Comments
@slavapestov, is this something obvious we can remove? |
Probably. swift-corelibs-foundation even has a workaround for this, defining an empty stub for objc_retainAutoreleasedReturnValue(). @jckarter should remember the details – IIRC it wasn't as simple as just removing the function, because of memory management issues. |
We should be able to safely call |
The advantage of treating them as |
Comment by Gregor Milos (Grzegorz Miłoś) (JIRA) FWIW, what I really want in my example is +1 (a.k.a. |
Yeah, that's what we usually do for native Swift closures. On Darwin we use a +0 convention for returns from blocks because we need to be compatible with ObjC, but we could potentially do something different on other platforms. |
Comment by Gregor Milos (Grzegorz Miłoś) (JIRA) @jckarter on Linux, for new code, it makes far more sense to follow same memory management conventions as in native Swift. However, there may be some code in libdispatch and/or Foundation that assumes ObjC conventions. In fact, taking into account what @slavapestov was saying, there likely is some exposure. |
Yeah, that's the tradeoff. In the short term, we could support invoking existing C functions with a +0 convention as "unowned", and flag returning a reference-counted value from a Swift closure used as a block or C function pointer as unsupported. |
Comment by Gregor Milos (Grzegorz Miłoś) (JIRA) Oh nooo... Please don't unsupport that 🙂. That's exactly what I want to use! (returning reference counted values [blocks]). My current usecase for this was wrapping a high-performance C++ server (Proxygen) and exposing matching API in Swift. This was done with a series of callbacks. Since those callbacks need to capture state it forced me to go down the route of using C blocks. The callbacks chain, because a factory class is represented by a block with block return type. So atm it's easy for me to stub |
Stubbing out |
You could also use an `Unmanaged` return value to manually reference count the object across the boundary. |
Comment by Gregor Milos (Grzegorz Miłoś) (JIRA) @jckarter your comment about unsafety confuses me. Especially given the fact the code I wrote seems to be behaving safely.
|
The caller can't know whether the value was added to an autorelease pool or not. Therefore, it can't know whether it has to release or not. (The fact that there are no autorelease pools without the ObjC runtime around shouldn't change this.) Swift has to either always return blocks at +1 on non-ObjC runtimes, or has to disallow returning bare blocks. (Unfortunately Unmanaged doesn't play well with closures right now.) |
Comment by Gregor Milos (Grzegorz Miłoś) (JIRA) @belkadan: stubbed |
It's mostly that it's not consistent with Apple platforms. A cross-platform C caller would not be able to assume +1, and that seems like a pretty lousy story. |
Comment by Gregor Milos (Grzegorz Miłoś) (JIRA) Right, different policies on different platforms is certainly not great. Perhaps we could make it little safer by requiring some magic Is there an alternative solution to my root issue?
|
When ObjC interop is not enabled, we shouldn't be emitting calls to `objc_retainAutoreleasedReturnValue()` as that function might not exist. Call `swift_retain()` instead, to balance the `swift_release()` of the returned value. Fixes apple#47846, apple#45359. rdar://23335318
When ObjC interop is not enabled, we shouldn't be emitting calls to `objc_retainAutoreleasedReturnValue()` as that function might not exist. Call `swift_retain()` instead, to balance the `swift_release()` of the returned value. Fixes apple#47846, apple#45359. rdar://23335318
Attachment: Download
Additional Detail from JIRA
md5: 89cbd7095952971a44b28957ee5b5db8
relates to:
Issue Description:
When building Swift code, which calls to a C API taking block with block return value, generates false
objc_autoreleaseReturnValue
dependency.From the attached minimal reproduction:
The
objc_autoreleaseReturnValue
dependency doesn't exist on Linux. I was able to verify that the code builds and works when defining the symbol myself (simple identity function). This can be tested building withmake clean && make CFLAGS=-DDEFINE_AUTORELEASE_RETURN_VALUE
Explicit
Block_retain/Block_release
should be used to manage return value lifecycle instead.The text was updated successfully, but these errors were encountered: