Adding `move_value [lexical]` and `begin_borrow [lexical]` should happen
all the time at this point. Remove the ability to omit these
instructions and update the corresponding tests.
The effect of passing -enable-copy-propagation is both to enable the
CopyPropagation pass to shorten object lifetimes and also to enable
lexical lifetimes to ensure that object lifetimes aren't shortened while
a variable is still in scope and used.
Add a new flag, -enable-lexical-borrow-scopes=true to override
-enable-copy-propagation's effect (setting it to ::ExperimentalLate) on
SILOptions::LexicalLifetimes that sets it to ::Early even in the face of
-enable-copy-propagation. The old flag -disable-lexical-lifetimes is
renamed to -enable-lexical-borrow-scopes=false but continues to set that
option to ::Off even when -enable-copy-propagation is passed.
Only issue weak lifetime warnings for users who select object lifetime
optimization. The risk of spurious warnings outweighs the benefits.
Although the warnings are generally useful regardless of the level of
optimization, it isn't really critical to issue them unless the optimizer
aggressively shrinks reference lifetimes.
Fixes rdar://79146338 Xcode warns that "referenced object is
deallocated here" but that object was passed into a method that causes
strong retention)
This
1. fixes a bug, where we didn't consider that an object can escape via a function call. The pass issued a false warning in this case.
rdar://76115467
2. improves the accuracy by doing a simple form of interprocedural analysis. E.g. it now can see if a weak store is done in a called function.
rdar://76297286
The DiagnoseLifetimeIssuesPass pass prints a warning if an object is stored to a weak property (or is weakly captured) and destroyed before the property (or captured reference) is ever used again.
This can happen if the programmer relies on the lexical scope to keep an object alive, but copy-propagation can shrink the object's lifetime to its last use.
For example:
func test() {
let k = Klass()
// k is deallocated immediately after the closure capture (a store_weak).
functionWithClosure({ [weak k] in
// crash!
k!.foo()
})
}
Unfortunately this pass can only catch simple cases, but it's better than nothing.
rdar://73910632