Skip to content

Commit ac0e966

Browse files
committed
SILGen: Fix potential use-after-free in @_backDeploy coroutines.
The SIL verifier has identified an issue with the SIL generated for property accessors structured like this: ``` public struct S { @available(macOS, introduced: 12.0) @_backDeploy(before: macOS 13.0) public var x: String { _read { yield "x" } } } ``` The emitted SIL is invalid because the value `%9` is used after `end_apply` may have ended the lifetime of the value: ``` bb1: %8 = function_ref @$s4test1SV1xSSvrTwB : $@yield_once @convention(method) (S) -> @yields @guaranteed String9 (%9, %10) = begin_apply %8(%0) : $@yield_once @convention(method) (S) -> @yields @guaranteed String end_apply %10 yield %9 : $String, resume bb3, unwind bb2 ``` The fix is to move the `end_apply` to the resume and unwind blocks, after the value has been yielded to the caller. Resolves rdar://96879247
1 parent d6e5805 commit ac0e966

File tree

2 files changed

+6
-3
lines changed

2 files changed

+6
-3
lines changed

lib/SILGen/SILGenBackDeploy.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,16 @@ static void emitBackDeployForwardApplyAndReturnOrThrow(
108108
rawResults.push_back(result);
109109

110110
auto token = rawResults.pop_back_val();
111-
SGF.B.createEndApply(loc, token);
112111
SGF.B.createYield(loc, rawResults, resumeBB, unwindBB);
113112

114113
// Emit resume block.
115114
SGF.B.emitBlock(resumeBB);
115+
SGF.B.createEndApply(loc, token);
116116
SGF.B.createBranch(loc, SGF.ReturnDest.getBlock());
117117

118118
// Emit unwind block.
119119
SGF.B.emitBlock(unwindBB);
120+
SGF.B.createEndApply(loc, token);
120121
SGF.B.createBranch(loc, SGF.CoroutineUnwindDest.getBlock());
121122
return;
122123
}

test/SILGen/back_deploy_attribute_accessor_coroutine.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,27 @@ public struct TopLevelStruct {
3232
// CHECK: [[UNAVAIL_BB]]:
3333
// CHECK: [[FALLBACKFN:%.*]] = function_ref @$s11back_deploy14TopLevelStructV8propertyACvrTwB : $@yield_once @convention(method) (TopLevelStruct) -> @yields TopLevelStruct
3434
// CHECK: ([[YIELD_RES:%.*]], [[YIELD_TOK:%.*]]) = begin_apply [[FALLBACKFN]]([[BB0_ARG]]) : $@yield_once @convention(method) (TopLevelStruct) -> @yields TopLevelStruct
35-
// CHECK: end_apply [[YIELD_TOK]]
3635
// CHECK: yield [[YIELD_RES]] : $TopLevelStruct, resume [[UNAVAIL_RESUME_BB:bb[0-9]+]], unwind [[UNAVAIL_UNWIND_BB:bb[0-9]+]]
3736
//
3837
// CHECK: [[UNAVAIL_UNWIND_BB]]:
38+
// CHECK: end_apply [[YIELD_TOK]]
3939
// CHECK: br [[UNWIND_BB:bb[0-9]+]]
4040
//
4141
// CHECK: [[UNAVAIL_RESUME_BB]]:
42+
// CHECK: end_apply [[YIELD_TOK]]
4243
// CHECK: br [[RETURN_BB:bb[0-9]+]]
4344
//
4445
// CHECK: [[AVAIL_BB]]:
4546
// CHECK: [[ORIGFN:%.*]] = function_ref @$s11back_deploy14TopLevelStructV8propertyACvr : $@yield_once @convention(method) (TopLevelStruct) -> @yields TopLevelStruct
4647
// CHECK: ([[YIELD_RES:%.*]], [[YIELD_TOK:%.*]]) = begin_apply [[ORIGFN]]([[BB0_ARG]]) : $@yield_once @convention(method) (TopLevelStruct) -> @yields TopLevelStruct
47-
// CHECK: end_apply [[YIELD_TOK]]
4848
// CHECK: yield [[YIELD_RES]] : $TopLevelStruct, resume [[AVAIL_RESUME_BB:bb[0-9]+]], unwind [[UAVAIL_UNWIND_BB:bb[0-9]+]]
4949
//
5050
// CHECK: [[UAVAIL_UNWIND_BB]]:
51+
// CHECK: end_apply [[YIELD_TOK]]
5152
// CHECK: br [[UNWIND_BB]]
5253
//
5354
// CHECK: [[AVAIL_RESUME_BB]]:
55+
// CHECK: end_apply [[YIELD_TOK]]
5456
// CHECK: br [[RETURN_BB]]
5557
//
5658
// CHECK: [[RETURN_BB]]:

0 commit comments

Comments
 (0)