It's permitted for a `witness_method` instruction to have multiple
type-dependent operands. This can happen when for example when one
local archetype is defined in terms of another.
rdar://159211502
It is like `zeroInitializer`, but does not actually initialize the memory.
It only indicates to mandatory passes that the memory is going to be initialized.
Immortal C++ foreign reference types get TrivialTypeLowering instead of ReferenceTypeLowering, since they do not have retain/release lifetime operations. This was tripping up an assertion in SILVerifier.
rdar://147251759 / resolves https://github.com/swiftlang/swift/issues/80065
Convert a bunch of places where we're dumping to stderr and calling
`abort` over to using `ABORT` such that the message gets printed to
the pretty stack trace. This ensures it gets picked up by
CrashReporter.
I think this was just an oversight. There is really no reason that this should
not match the rest of the SILVerifier w here we have moved from using #ifndef
NDEBUG to verificationEnabled checking.
Also, make it more tolerant to instructions and builtins, which are not explicitly handled.
This avoids crashes when new instructions are added. We got lucky that this didn't happen so far.
It derives the address of the first element of a vector, i.e. a `Builtin.FixedArray`, from the address of the vector itself.
Addresses of other vector elements can then be derived with `index_addr`.
Store specialize witness tables in a separate lookup table in the module. This allows that for a normal conformance there can exist the original _and_ a specialized witness table.
Also, add a boolean property `isSpecialized` to `WitnessTable` which indicates whether the witness table is specialized or not.
This is a value operation that can work just fine on lowered types,
so there's no need to carry along a formal type. Make the value/address
duality clearer, and enforce it in the verifier.
InteriorLiveness has a new "visitInnerUses" mode used by DestroyHoisting. That
mode may visit dependent values, which was not valid for noescape
closures. ClosureLifetimeFixup inserts destroys of noescape closures after the
destroys of the captures. So following such dependent value could result in an
apparent use-after-destroy. This causes DestroyHoisting to insert redundant
destroys.
Fix: InteriorUses will conservatively only follow dependent values if they are
escapable. Non-escapable values, like noescape closures are now considered
escapes of the original value that the non-escapable value depends on. This can
be improved in the future, but we may want to rewrite ClosureLifetimeFixup first.
Fixes the root cause of: rdar://146142041
Only return false if the visitor returns false. Clients were ignoring the
result.
If the BorrowingOperand does not create a borrow scope, call visitUnknownUse
instead.
Until we have complete lifetimes, to avoid breaking code that cannot handle dead
defs, consider a dead borrow scope to be an unknown use.
The check is not perfect, because it only checks that the base operand is alive _at_ the mark_dependence.
Ideally it should check that the base operand is alive during the whole lifetime of the value operand.
This is necessary to fix a recent OSSA bug that breaks common occurrences on
mark_dependence [nonescaping]. Rather than reverting that change above, we make
forward progress toward implicit borrows scopes, as was the original intention.
In the near future, all InteriorPointer instructions will create an implicit
borrow scope. This means we have the option of not emitting extraneous
begin/end_borrow instructions around intructions like ref_element_addr,
open_existential, and project_box. After that, we can also migrate
GuaranteedForwarding instructions like tuple_extract and struct_extract.
The problem with `is_escaping_closure` was that it didn't consume its operand and therefore reference count checks were unreliable.
For example, copy-propagation could break it.
As this instruction was always used together with an immediately following `destroy_value` of the closure, it makes sense to combine both into a `destroy_not_escaped_closure`.
It
1. checks the reference count and returns true if it is 1
2. consumes and destroys the operand