mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
The checker already verifies that no non-destroy consuming users occur after any `move_value`s corresponding to `consume` operators applied to a value. There may, however, be _destroy_ users after it. Previously, the checker did not shorten the lifetime from those destroys up to `move_value`s that appear after those `move_value`s. The result was that the value's lifetime didn't end at the `consume`. Here, the checker is fixed to rewrite the lifetimes so that they both end at `consume`s and also maintain their lexical lifetimes on paths away from the `consume`s. This is done by using `OwnedValueCanonicalization`/`CanonicalizeOSSALifetime`. Specifically, it passes the `move_value`s that correspond to source-level `consume`s as the `lexicalLifetimeEnds` to the canonicalizer. Typically, the canonicalizer retracts the lexical lifetime of the value from its destroys. When these `move_value`s are specified, however, instead it retracts them from the lifetime boundary obtained by maximizing the lifetime within its original lifetime while maintaining the property that the lifetime ends at those `move_value`s. rdar://113142446
32 lines
1.1 KiB
Plaintext
32 lines
1.1 KiB
Plaintext
// RUN: %target-sil-opt -opt-mode=none -enable-sil-verify-all %s -sil-consume-operator-copyable-values-checker | %FileCheck %s
|
|
// RUN: %target-sil-opt -opt-mode=speed -enable-sil-verify-all %s -sil-consume-operator-copyable-values-checker | %FileCheck %s
|
|
|
|
sil_stage raw
|
|
|
|
import Builtin
|
|
|
|
class X {}
|
|
|
|
struct S {}
|
|
|
|
sil @getX : $@convention(thin) () -> @owned X
|
|
sil @takeX : $@convention(thin) (@owned X) -> S
|
|
|
|
// CHECK-LABEL: sil [ossa] @testit : {{.*}} {
|
|
// CHECK-NOT: copy_value
|
|
// CHECK-LABEL: } // end sil function 'testit'
|
|
sil [ossa] @testit : $@convention(thin) () -> () {
|
|
%getX = function_ref @getX : $@convention(thin) () -> @owned X
|
|
%x = apply %getX() : $@convention(thin) () -> @owned X
|
|
%begin = move_value [lexical] [var_decl] %x : $X
|
|
debug_value %begin : $X, let, name "x"
|
|
%copy = copy_value %begin : $X
|
|
%consume = move_value [allows_diagnostics] %copy : $X
|
|
%takeX = function_ref @takeX : $@convention(thin) (@owned X) -> S
|
|
apply %takeX(%consume) : $@convention(thin) (@owned X) -> S
|
|
destroy_value %begin : $X
|
|
%retval = tuple ()
|
|
return %retval : $()
|
|
}
|
|
|