Skip to content

Commit 9861422

Browse files
committed
[SIL] Key consume checking off var_decl attr.
Previously, the lexical attribute on begin_borrow instructions was used. This doesn't work for values without lexical lifetimes which are consumed, e.g. stdlib CoW types. Here, the new var_decl attribute on begin_borrow is keyed off of instead. This flag encodes exactly that a value corresponds to a source-level VarDecl, which is the condition under which checking needs to run. rdar://118059326
1 parent 9bb0187 commit 9861422

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

lib/SILOptimizer/Mandatory/ConsumeOperatorCopyableValuesChecker.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ bool ConsumeOperatorCopyableValuesChecker::check() {
410410
for (auto &block : *fn) {
411411
for (auto &ii : block) {
412412
if (auto *bbi = dyn_cast<BeginBorrowInst>(&ii)) {
413-
if (bbi->isLexical() && !bbi->getType().isMoveOnly()) {
413+
if (bbi->isFromVarDecl() && !bbi->getType().isMoveOnly()) {
414414
LLVM_DEBUG(llvm::dbgs()
415415
<< "Found lexical lifetime to check: " << *bbi);
416416
valuesToCheck.insert(bbi);

lib/SILOptimizer/Utils/CanonicalizeInstruction.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,11 @@ eliminateSimpleBorrows(BeginBorrowInst *bbi, CanonicalizeInstruction &pass) {
485485
!isNestedLexicalBeginBorrow(bbi)))
486486
return next;
487487

488+
// Borrow scopes representing a VarDecl can't be eliminated during the raw
489+
// stage because they may be needed for diagnostics.
490+
if (bbi->isFromVarDecl() && (bbi->getModule().getStage() == SILStage::Raw))
491+
return next;
492+
488493
// We know that our borrow is completely within the lifetime of its base value
489494
// if the borrow is never reborrowed. We check for reborrows and do not
490495
// optimize such cases. Otherwise, we can eliminate our borrow and instead use

test/SILOptimizer/moveonly_objectchecker_diagnostics.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public func borrowVal(_ x: borrowing KlassPair) {}
2626
public func borrowVal(_ x: borrowing AggGenericStruct<String>) {}
2727
public func borrowVal<T>(_ x: borrowing AggGenericStruct<T>) {}
2828
public func borrowVal(_ x: borrowing EnumTy) {}
29+
public func borrowVal(_ x: borrowing String) {}
2930

3031
public func consumeVal(_ x: __owned Klass) {}
3132
public func consumeVal(_ x: __owned FinalKlass) {}
@@ -4262,3 +4263,22 @@ func testMyEnum() {
42624263
}
42634264
}
42644265
}
4266+
4267+
4268+
func rdar_118059326_example1() {
4269+
@_noEagerMove let thinger = "hello" // expected-error {{'thinger' used after consume}}
4270+
_ = consume thinger // expected-note {{consumed}}
4271+
borrowVal(thinger) // expected-note {{used}}
4272+
}
4273+
4274+
func withSadness<T>(_ execute: () throws -> T) rethrows -> T {
4275+
try execute()
4276+
}
4277+
4278+
func rdar_118059326_example2(_ path: String) {
4279+
let decoded = withSadness { // expected-error {{'decoded' used after consume}}
4280+
return path
4281+
}
4282+
_ = consume decoded // expected-note {{consumed}}
4283+
borrowVal(decoded) // expected-note {{used}}
4284+
}

0 commit comments

Comments
 (0)