[silgen] Create a function level scope when open coding implicit value initializers. #32089
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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:
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.
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