Skip to content

[silgen] Create a function level scope when open coding implicit value initializers. #32089

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

gottesmm
Copy link
Contributor

The Original Bug

In ffbfcfa, we fixed a bug around implicit
value initializers but did not cherry-pick it to 5.3. While investigating a bug
that turned out to be that same bug (no worries!), I noticed that there is
additional code that is "unsafely" correct in this area and that while
ffbfcfa is correct in the small, we can expand
on the fix to prevent future bugs.

The Larger Bug

Here we are still open coding using ManagedValue/Cleanup APIs /without/ a top
level function scope. The code is only correct since we never emit unconditional
cleanups and always manually forward conditional cleanups. If we did not do
either of these things, we would have another instance of this bug, namely a
cleanup that is never actually emitted. So the code on master today is correct,
albeit unsafe, and we already have coverage for this (namely the test case from
ffbfcfa).

That being said, in general when working with ManagedValue APIs (especially in
utility functions) we assume that we have a scope already created for us by our
caller. So by fixing this issue we are standardizing to safer SILGen invariants.

Building on ffbfcfa

This commit builds on the shoulders of ffbfcfa
by adding the function level scope mentioned in the previous section so that we
are now "safely" correct.

While looking at this I also realized that just using a normal scope when open
coding here may be a bit bugprone for open coding situations like this since:

  1. If one just creates a scope in open coding situations, the scope will fire at
    end of the c++ function /after/ one has probably emitted a return.

  2. Once one has emitted the return, the insertion point will no longer be set
    implying =><=.

To avoid this, I created a move only composition type on top of Scope called
AssertingManualScope. This type just asserts in its destructor if the scope it
contains has not been popped yet.

While, one can pop it by ones self, I added an overload of createReturnInst on
SILGenBuilder that also takes an AssertingManualScope and pops it at the
appropriate time.

So now when performing simple open coding tasks, we have the ability to in code
tie together the function level scope to the actual creation of return inst,
simulating the hand-off of lifetimes/resources from caller/callee that often
happens in the epilog of functions.

rdar://problem/63189210

…e initializers.

The Original Bug
----------------

In ffbfcfa, we fixed a bug around implicit
value initializers but did not cherry-pick it to 5.3. While investigating a bug
that turned out to be that same bug (no worries!), I noticed that there is
additional code that is "unsafely" correct in this area and that while
ffbfcfa is correct in the small, we can expand
on the fix to prevent future bugs.

The Larger Bug
--------------

Here we are still open coding using ManagedValue/Cleanup APIs /without/ a top
level function scope. The code is only correct since we never emit unconditional
cleanups and always manually forward conditional cleanups. If we did not do
either of these things, we would have another instance of this bug, namely a
cleanup that is never actually emitted. So the code on master today is correct,
albeit unsafe, and we already have coverage for this (namely the test case from
ffbfcfa).

That being said, in general when working with ManagedValue APIs (especially in
utility functions) we assume that we have a scope already created for us by our
caller. So by fixing this issue we are standardizing to safer SILGen invariants.

Building on ffbfcfa
----------------------------------------------------

This commit builds on the shoulders of ffbfcfa
by adding the function level scope mentioned in the previous section so that we
are now "safely" correct.

While looking at this I also realized that just using a normal scope when open
coding here may be a bit bugprone for open coding situations like this since:

1. If one just creates a scope in open coding situations, the scope will fire at
   end of the c++ function /after/ one has probably emitted a return.

2. Once one has emitted the return, the insertion point will no longer be set
   implying =><=.

To avoid this, I created a move only composition type on top of Scope called
AssertingManualScope. This type just asserts in its destructor if the scope it
contains has not been popped yet.

While, one can pop it by ones self, I added an overload of createReturnInst on
SILGenBuilder that also takes an AssertingManualScope and pops it at the
appropriate time.

So now when performing simple open coding tasks, we have the ability to in code
tie together the function level scope to the actual creation of return inst,
simulating the hand-off of lifetimes/resources from caller/callee that often
happens in the epilog of functions.

<rdar://problem/63189210>
@gottesmm gottesmm requested review from slavapestov and jckarter May 29, 2020 22:04
@gottesmm
Copy link
Contributor Author

@swift-ci test

1 similar comment
@gottesmm
Copy link
Contributor Author

@swift-ci test

@gottesmm
Copy link
Contributor Author

@swift-ci test windows platform

@gottesmm
Copy link
Contributor Author

gottesmm commented Jun 1, 2020

@jckarter ping?

@jckarter
Copy link
Contributor

jckarter commented Jun 2, 2020

Makes sense.

@gottesmm gottesmm merged commit 6fa4874 into swiftlang:master Jun 2, 2020
@gottesmm gottesmm deleted the pr-305c2fadbc4ce607a2a7ff330c5ab9204bfd4427 branch June 2, 2020 18:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants