Preserve ownership for empty non-trivial structs. This currently applies to
~Escapable structs. People often use empty structs to investigate language
behavior. They should behave just like a struct that wraps a
pointer.
Previously, this would crash later during OSSA lifetime completion:
Assertion failed: (isa<UnreachableInst>(block->getTerminator())),
function computeRegion, file OSSALifetimeCompletion.cpp.
Only generate code lazily for such functions, i.e. only if such a function is referenced from already generated code.
This is achieved by converting the SILLinkage for `public_external` functions to `internal` instead of `public in IRGenPrepare.
When visiting a consuming use of a move-only value (which can be
produced by a forwarding operation), the inner rewriter must bail out.
Otherwise, it would produce a copy of that move-only value.
rdar://142520491
Allow rewriting of arguments to bail out. This is necessary because not
all forwarding instructions allow rewriting of forward(copy) as
copy(forward) (e.g. when forward produces a move-only value).
So far we only checked the ownership of incoming values.
But even if the incoming instruction has no ownership, the argument may have.
This can happen with enums which are constructed with a non-payload case:
%1 = enum $Optional<C>, #Optional.none!enumelt
br bb3(%1)
bb1(%3 : @owned $Optional<C>):
Fixes an ownership verification error:
rdar://142506300
The operands to the original apply are cast via an ownership forwarding
instruction to the appropriate type for the rewritten apply.
```
%converted = convert_function %original to $(NewTy) -> ()
apply %converted(%operand)
```
->
```
%cast = cast %operand to $OriginalTy
apply %original(%cast)
```
Previously, when an original operand is owned but the new apply does not
consume that operand, the newly added cast would consume the original
operand (an owned value)--something the original code being replaced did
not do.
```
%converted = convert_function %original to $(NewTy) -> ()
apply %converted(%operand : @guaranteed)
// %operand remains available
```
->
```
%cast = cast %operand to $OriginalTy // consumes %operand!
apply %original(%cast : @guaranteed)
// %operand is not available!
```
This is incorrect for the complementary reasons that the result of the
cast is leaked and any uses of the original operand subsequent to the
new apply are uses-after-consume.
Here, this is fixed by borrowing the original operand before casting in
this case.
rdar://142570727
Since `move_value` is a destroying operation, the adjoint of `y = move_value x` should be `adj[x] += adj[y]; adj[y] = 0` instead of just `adj[x] += adj[y]`.
I did the correct thing for indirect parameters, but did not do the correct
thing for direct parameters. This is now fixed with some tests to boot.
rdar://141631655
Don't use previously found owned concrete values in ossa. They will consumed by
forwarding operations like init_existential_ref. Instead create an unconditional cast
of the opened existential to concrete type and use that to create a concrete apply.
Put AvailabilityRange into its own header with very few dependencies so that it
can be included freely in other headers that need to use it as a complete type.
NFC.
Right now it is basically a version of nonisolated beyond a few simple cases
like constructors/destructors where we are pretty sure we want to not support
this.
This is part of my bringup strategy for changing nonisolated/unspecified to be
caller isolation inheriting.
Which consists of
* removing redundant `address_to_pointer`-`pointer_to_address` pairs
* optimize `index_raw_pointer` of a manually computed stride to `index_addr`
* remove or increase the alignment based on a "assumeAlignment" builtin
This is a big code cleanup but also has some functional differences for the `address_to_pointer`-`pointer_to_address` pair removal:
* It's not done if the resulting SIL would result in a (detectable) use-after-dealloc_stack memory lifetime failure.
* It's not done if `copy_value`s must be inserted or borrow-scopes must be extended to comply with ownership rules (this was the task of the OwnershipRAUWHelper).
Inserting copies is bad anyway.
Extending borrow-scopes would only be required if the original lifetime of the pointer extends a borrow scope - which shouldn't happen in save code. Therefore this is a very rare case which is not worth handling.