-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Use uninitialized dealloc in swift_deallocError #19059
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
Conversation
I don't think this is the correct fix, since the error is initialized. @mikeash, have we seen anything like this? |
@jrose-apple As I understand Or what you mean "initialized" |
I wasn't aware of any problems with this, but this does look like the correct fix. The
This fix adjusts the non-interop version to match. Assuming the ObjC version is correct (I imagine someone would have noticed by now if it weren't) this should be good. |
My mistake! Can you add a test for this, then, Anton? test/stdlib/ErrorBridged.swift seems to be a good place. |
Whoops, my poor Markdown skills resulted in most of the comment being hidden. Since it describes that the function is intended to deallocate an error object which has already been destroyed, that's kind of important! |
@jrose-apple of course will do |
@jrose-apple As I see |
Ah, right. Well, we can't test NSError specifically in the Swift repo because swift-corelibs-foundation isn't available in the Swift tests, but this seems like a problem that would occur with any Error, or maybe any class that conforms to Error (as opposed to the usual struct or enum). If that's the case, then adding it to test/stdlib/Error.swift is probably good. |
With any error marked as |
I was wrong simple enum errors also produce assertions. But I am still not clear how to test it. |
The test should automatically fail on crash by default, so you should be able to make a simple test case that just triggers the failure case and returns. You can try running it with and without your fix to make sure it fails when it's supposed to. |
You can have perhaps a separate PR against swift-corelibs-Foundation to add a test there, which is where we plan to have bridging tests for non-ObjC bridging. |
Looks like original issue already fixed in master by #18937 Maybe still actual in some other cases but I don't them. |
It can't be called on a completely uninitialized buffer. It calls through to either |
@mikeash Can you look into this? Original code which leads to issue:
SIL generated by swift-DEVELOPMENT-SNAPSHOT-2018-08-26-a-ubuntu16.04:
SIL generated by swift-DEVELOPMENT-SNAPSHOT-2018-09-04-a-ubuntu16.04:
As you can see But I dont know is any other code can produce |
I recently changed the order of operations for existential formations so that the box allocation occurs lazily. This fix still looks correct. We'd get similar codegen if a call throws while trying to initialize the box in-place, as in:
|
@jckarter thanks for example |
a17b556
to
8856fb1
Compare
Test added. Can anyone trigger ci? |
@swift-ci Please test |
Build failed |
Build failed |
All right, merging. Thanks, Anton! |
Current of implementation
swift_deallocError
produce assertion in code like thisAssertion is here https://github.com/apple/swift/blob/master/stdlib/public/runtime/HeapObject.cpp#L678
When swift_deallocError called box have unowned count = 1, strong count = 0 and deiniting = false.
I am not sure is it correct way to avoid assertion, and would it work properlly in all cases. So would be cool if somebody looks into this.