diff --git a/lib/SILOptimizer/Mandatory/ConsumeOperatorCopyableValuesChecker.cpp b/lib/SILOptimizer/Mandatory/ConsumeOperatorCopyableValuesChecker.cpp index 3704d8a0a8c82..724203c1a24e7 100644 --- a/lib/SILOptimizer/Mandatory/ConsumeOperatorCopyableValuesChecker.cpp +++ b/lib/SILOptimizer/Mandatory/ConsumeOperatorCopyableValuesChecker.cpp @@ -157,6 +157,11 @@ bool CheckerLivenessInfo::compute() { return false; } } + } else if (isa(user)) { + if (liveness->updateForBorrowingOperand(use) != + InnerBorrowKind::Contained) { + return false; + } } // FIXME: this ignores all other forms of Borrow ownership, such as // partial_apply [onstack] and mark_dependence [nonescaping]. diff --git a/test/SILOptimizer/consume_operator_kills_copyable_values.swift b/test/SILOptimizer/consume_operator_kills_copyable_values.swift index e6ac631358637..a5d786ccaf040 100644 --- a/test/SILOptimizer/consume_operator_kills_copyable_values.swift +++ b/test/SILOptimizer/consume_operator_kills_copyable_values.swift @@ -6,6 +6,10 @@ public class Klass {} public class SubKlass1 : Klass {} public class SubKlass2 : Klass {} +struct A { + var prop = "" +} + ////////////////// // Declarations // ////////////////// @@ -14,6 +18,14 @@ func consumingUse(_ k: __owned Klass) {} var booleanValue: Bool { false } func nonConsumingUse(_ k: Klass) {} +func consumeValue(_ v: consuming V) {} +func borrowValue(_ v: borrowing V) {} +func useValue(_ v: V) {} + +func consumeA(_ a: consuming A) {} +func borrowA(_ a: borrowing A) {} +func useA(_ a: A) {} + /////////// // Tests // /////////// @@ -424,3 +436,37 @@ public func deferTest(_ x: __owned Klass) { // expected-error {{'x' used after c } print("do Something") } + + +///////////////////////// +// Local Binding Tests // +///////////////////////// + +func testLocalBindingUseAfterConsumeGenerics() { + let a = A() // expected-error {{'a' used after consume}} + _ = consume a // expected-note {{consumed here}} + consumeValue(a) // expected-note {{used here}} + borrowValue(a) // expected-note {{used here}} + useValue(a) // expected-note {{used here}} +} + +func testLocalBindingUseAfterConsumeNoGenericFuncs() { + let a = A() // expected-error {{'a' used after consume}} + _ = consume a // expected-note {{consumed here}} + + consumeA(a) // expected-note {{used here}} + borrowA(a) // expected-note {{used here}} + useA(a) // expected-note {{used here}} +} + +// https://github.com/swiftlang/swift/issues/83277 +func test_83277() { + let values = [1, 2, 3] // expected-error {{'values' used after consume}} + var newValues = consume values // expected-note {{consumed here}} + newValues.append(4) + + _ = values.count // expected-note {{used here}} + _ = values[0] // expected-note {{used here}} + _ = values.first // expected-note {{used here}} + _ = values.last // expected-note {{used here}} +}