-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[silgenpattern] Fix a leak in tuple pattern emission. #21745
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
[silgenpattern] Fix a leak in tuple pattern emission. #21745
Conversation
@swift-ci test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Michael talked me through this in person. LGTM.
JoeG asked me to fix this comment: https://github.com/apple/swift/pull/21745/files#diff-95c4d5d527b6ea06630be4cf0edd94f3R1550 I am going to fix that and then do a smoke test/merge since I already did a full test. |
Today SILGenPattern maintains the following invariants: 1. All values passed into a switch must be either TakeAlways or BorrowAlways and loadable input values will be loaded. 2. Loadable types passed to a subtree must be loaded. 3. TakeOnSuccess can only occur with address only types and only in subtrees. 4. A TakeOnSuccess value must go through "fake borrowing" (i.e. forward/unforwarding) to ensure that along failing cases, we properly re-enable the cleanup on the aggregate. This means that TakeOnSuccess can never be handled as a loadable value with ownership enabled and that any take_on_success value since the original cleanup on the parent value was disabled must be at +1. 5. We use BorrowAlways instead of TakeOnSuccess for objects to express the notion that the object is not owned by the sub-tree. The bug in this tuple code occured at the a place in the code where we go from an address only parent type to a loadable subtype via TakeOnSuccess. I was trying to follow (5) and thus I converted the subvalue to use a {load_borrow, BorrowAlways}. The problem with this is that I lost the cleanup from the tuple subvalue since take_on_success is just simulating +0 and thus entails having a cleanup for each of the underlying tuple values. The fix here was to: * Create a cleanup for the loadable subvalue leaving it in memory. This address version of the subvalue we use for the purposes of unforwarding. This avoids (4). * load_borrow the subvalue and pass that off to the subtree. This ensures that we respect (2), (3), (4). * Unforward in the failure case the in memory subvalue. This gives us both characteristics as well as in the future the possibility of enforcing via the ownership verifier that the borrow ends before the destroy_addr. I also sprinkled some assertions liberally to maintain invariants. rdar://47034816
aa331d2
to
a53e351
Compare
@swift-ci smoke test and merge |
Today SILGenPattern maintains the following invariants:
All values passed into a switch must be either TakeAlways or BorrowAlways and
loadable input values will be loaded.
Loadable types passed to a subtree must be loaded.
TakeOnSuccess can only occur with address only types and only in subtrees.
A TakeOnSuccess value must go through "fake borrowing"
(i.e. forward/unforwarding) to ensure that along failing cases, we properly
re-enable the cleanup on the aggregate. This means that TakeOnSuccess can
never be handled as a loadable value with ownership enabled and that any
take_on_success value since the original cleanup on the parent value was
disabled must be at +1.
We use BorrowAlways instead of TakeOnSuccess for objects to express the
notion that the object is not owned by the sub-tree.
The bug in this tuple code occured at the a place in the code where we go from
an address only parent type to a loadable subtype via TakeOnSuccess. I was
trying to follow (5) and thus I converted the subvalue to use a {load_borrow,
BorrowAlways}. The problem with this is that I lost the cleanup from the tuple
subvalue since take_on_success is just simulating +0 and thus entails having a
cleanup for each of the underlying tuple values.
The fix here was to:
version of the subvalue we use for the purposes of unforwarding. This avoids
(4).
we respect (2), (3), (4).
This gives us both characteristics as well as in the future the possibility of
enforcing via the ownership verifier that the borrow ends before the
destroy_addr.
I also sprinkled some assertions liberally to maintain invariants.
rdar://47034816