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.
In OSSA, the `partial_apply [on_stack]` instruction produces a value
with odd characteristics that correspond to the fact that it is lowered
to a stack-allocating instruction. Among these characteristics is the
fact that copies of such values aren't load bearing.
When visiting the lifetime-ending uses of a `partial_apply [on_stack]`
the lifetime ending uses of (transitive) copies of the partial_apply
must be considered as well. Otherwise, the borrow scope it defins may be
incorrectly short:
```
%closure = partial_apply %fn(%value) // borrows %value
%closure2 = copy_value %closure
destroy_value %closure // does _not_ end borrow of %value!
...
destroy_value %closure2 // ends borrow of %value
...
destroy_value %value
```
Furthermore, _only_ the final such destroys actually count as the real
lifetime ends. At least one client (OME) relies on
`visitOnStackLifetimeEnds` visiting at most a single lifetime end on any
path.
Rewrite the utility to use PrunedLiveness, tracking only destroys of
copies and forwards. The final destroys are the destroys on the
boundary.
rdar://142636711
`end_init_let_ref` instructions are inserted in class initializers after all fields are initialized.
It's important to look through such instructions when checking the `isLexical` property of a value.
Fixes a mis-compile due to shrinking a lexical liferange of a class.
Part of rdar://140229560
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
Improves OSSALifetimeCompletion to handle trivial variables when running from
SILGenCleanup. This only affects lifetime dependence diagnostics.
For the purpose of lifetime diagnostics, trivial local variables are only valid
within their lexical scope. Sadly, SILGen only know how to insert cleanup code
on normal function exits. SILGenCleanup relies on lifetime completion to fix
lifetimes on dead end paths.
%var = move_value [var_decl]
try_apply %f() : $..., normal bb1, error error
error:
extend_lifetime %var <=== insert this
unreachable
This allows Span to depend on local unsafe pointers AND be used within
throwing closures:
_ = a.withUnsafeBufferPointer {
let buffer = $0
let view = Span(_unsafeElements: buffer)
return view.withUnsafeBufferPointer(\.count)
}
The reason why I am doing this is that in certain cases the AST captures indices
will never actually line up with partial apply capture indices since we seem to
"smush" together closures and locally defined functions.
NOTE: The reason for the really small amount of test changes is that this change
does not change the actual output by design. The only cases I had to change were
a case where we began to emit a better diagnostic and also where I added code
coverage around _ and let _ since those require ignored_use to be implemented so
that they would be diagnosed (previously we just did not emit anything so we
couldn't emit the diagnostic at the SIL level).
rdar://142661388
This is used for synthetic uses like _ = x that do not act as a true use but
instead only suppress unused variable warnings. This patch just adds the
instruction.
Eventually, we can use it to move the unused variable warning from Sema to SIL
slimmming the type checker down a little bit... but for now I am using it so
that other diagnostic passes can have a SIL instruction (with SIL location) so
that we can emit diagnostics on code like _ = x. Today we just do not emit
anything at all for that case so a diagnostic SIL pass would not see any
instruction that it could emit a diagnostic upon. In the next patch of this
series, I am going to add SILGen support to do that.
According to the documentation,
```
It's ok if postDomBlocks has duplicates or extraneous blocks, as long
as they jointly post-dominate all live blocks that aren't on dead-end
paths.
```
Previously, though, duplicates resulted in trapping: each element of
`postDomBlocks` is pushed into a `BasicBlockWorklist`; when the second
occurrence of an element in `postDomBlocks` was encountered,
`BasicBlockWorklist::push` would trigger an assertion failure.
Here, `pushIfNotVisited` is called instead.
In embedded swift all the code is generated in the top-level module.
De-serialized witness tables for class existentials must be code-gen'd and therefore made non-external.
Fixes an unresolved symbol linker error.
rdar://142561676
A primary purpose of these features is to enable persistent references into their storage, so it's
reasonable to assume this property for these types and types containing them.
decl being accessed is correct. When this assumption fails due to a deserialization error
of its members, the use site accesses the layout with a wrong field offset, resulting in
UB or a crash. The deserialization error is currently not caught at compile time due to
LangOpts.EnableDeserializationRecovery being enabled by default to allow for recovery of some
of the deserialization errors at a later time. In case of member deserialization, however,
it's not necessarily recovered later on.
This PR tracks whether member deserialization had an error by recursively loading members and
checking for deserialization error, and fails and emits a diagnostic. It provides a way to
prevent resilience bypassing when the deserialized decl's layout is incorrect.
Resolves rdar://132411524
With the other fixes, it is now possible to build the stdlib without conditionalizing these
behaviors. This will allow libraries to adopt addressability as an experimental feature
without breaking ABI when interacting with other code.
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.
This attribute makes it so that a parameter of the annotated type, as well as
any type structurally containing that type as a field, becomes passed as
if `@_addressable` if the return value of the function has a dependency on
the parameter. This allows nonescapable values to take interior pointers into
such types.
I need this today to add the implicit isolated parameter... but I can imagine us
adding more implicit parameters in the future, so it makes sense to formalize it
so it is easier to do in the future.