Sometimes it can happen that a deinit function, which is imported from another module, has shared linkage.
In this case it is important to de-serialize the function body. Otherwise it would be illegal SIL.
Unfortunately I don't have a test case for this.
Some utilities, like Builder.insert(after:) pass a Builder object that
represents an insertion point. That insertion point is sometimes needed to
determine which instructions to create (endApply vs. abortApply). But there is
no way to recover the insertion point. We don't want to simply return an
instruction, because that could be interpreted in different ways. Instead we
provide insertion block, but only in those situations where it makes sense and can't
be used incorrectly.
And simplify enclosingAccessScope.
These two APIs now directly compute what is being asked for. Previously, each
invocation of enclosingAccessScope would recompute the base and all nested
scopes, but throw away that information. Sometimes we do not want to compute
that information, and other times we need all of it. Instead, provide separate
APIs that do exactly what is needed.
These are common APIs used by other utilities. This avoids quadratic traversals in those
cases. It is also easier to understand and debug.
These utilities will be used in LifetimeDependenceScopeFixup.
LifetimeDependence uses the address of the AccessBase to compute liveness. It is
more convenient to switch over all AccessBase kinds here rather than force all
clients to do it.
AccessBase already identifies a base address as either a .global (addressor) or
a .pointer. When initializing an AccessBase from a pointer_to_address, precisely
identify one of these kinds of accesses, rather than simply marking it
.unidentified.
This used to be a special case in the AccessPathWalker. But that's not the right
place to handle it.
Scope-ending instructions, like `end_borrow` are only irrelevant for RLE if the preceding load is not changed.
If it is changed from `load [copy]` -> `load [take]` the memory effects of those scope-ending instructions prevent that the `load [take]` will illegally mutate memory which is protected from mutation by the scope.
Fixes a memory verifier crash
rdar://139824805
When replacing an `enum` - `unchecked_enum_data` pair and the enum's operand is another non-trivial enum which is constructed with a trivial payload, and this happens in different basic blocks, we need to insert a compensating `destroy_value`.
Fixes a verifier crash
rdar://139787167
Checking if an access base is derived from a begin-borrow was too optimistic.
We have to bail for instructions which are not handled by the walker utilities.
Fixes a verifier crash.
rdar://139788357
For example:
```
%1 = begin_borrow %0
%2 = br bb1(%1, %1)
bb1(%3 : @reborrow @guaranteed, %4: @guaranteed):
// %4 is a guaranteed forwarding phi without any forwarding instructions between the begin_borrow and the incoming value.
```
Also improve the comments
Add `Value.constantAccessPath`. It is like `accessPath`, but ensures that the projectionPath only contains "constant" elements.
This means: if the access contains an `index_addr` projection with a non-constant index, the `projectionPath` does _not_ contain the `index_addr`.
Instead, the `base` is an `AccessBase.index` which refers to the `index_addr`.
I am adding this instruction to express artificially that two non-Sendable
values should be part of the same region. It is meant to be used in cases where
due to unsafe code using Sendable, we stop propagating a non-Sendable dependency
that needs to be made in the same region of a use of said Sendable value. I
included an example in ./docs/SIL.rst of where this comes up with @out results
of continuations.
* fix a false error if a derived class has different generic parameters than its base class
* fix a similar problem if a non-generic class derives from a generic class
* fix a compiler crash for calling a class method on a class metatype
rdar://137692055