Skip to content

Commit 18e3115

Browse files
committed
Move-only-check the result of modify coroutines.
Following #70333, do the same thing for modify coroutines, marking the result so that we check uses of the result to ensure it isn't consumed (without being reinitialized).
1 parent 96c87db commit 18e3115

File tree

6 files changed

+225
-46
lines changed

6 files changed

+225
-46
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4913,6 +4913,10 @@ SILGenFunction::emitBeginApply(SILLocation loc, ManagedValue fn,
49134913
auto value = yieldValues[i];
49144914
auto info = yieldInfos[i];
49154915
if (info.isIndirectInOut()) {
4916+
if (value->getType().isMoveOnly()) {
4917+
value = B.createMarkUnresolvedNonCopyableValueInst(loc, value,
4918+
MarkUnresolvedNonCopyableValueInst::CheckKind::ConsumableAndAssignable);
4919+
}
49164920
yields.push_back(ManagedValue::forLValue(value));
49174921
} else if (info.isConsumed()) {
49184922
if (value->getType().isMoveOnly()) {

lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,9 @@ static bool isInOutDefThatNeedsEndOfFunctionLiveness(
402402
return true;
403403
}
404404
}
405+
if (auto bai = dyn_cast_or_null<BeginApplyInst>(operand->getDefiningInstruction())) {
406+
return true;
407+
}
405408
}
406409

407410
return false;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %target-run-simple-swift | %FileCheck %s
2+
// REQUIRES: executable_test
3+
4+
struct NC: ~Copyable {
5+
deinit { print("destroy") }
6+
}
7+
8+
class C {
9+
private var _data: NC = NC()
10+
11+
var data: NC {
12+
_read { yield _data }
13+
_modify { yield &_data }
14+
}
15+
}
16+
17+
func borrow(_ nc: borrowing NC) {}
18+
func mod(_ nc: inout NC) {}
19+
20+
defer {
21+
// CHECK: starting
22+
print("starting")
23+
do {
24+
// CHECK-NEXT: destroy
25+
test(C())
26+
}
27+
// CHECK: done
28+
print("done")
29+
}
30+
func test(_ c: C) {
31+
borrow(c.data)
32+
borrow(c.data)
33+
34+
mod(&c.data)
35+
mod(&c.data)
36+
}

0 commit comments

Comments
 (0)