Skip to content

Commit 812ef34

Browse files
committed
[SILVerifier] a hop_to_executor may suspend the task.
With this change, the SILVerifier should now catch and reject the appearance of a hop_to_executor between the get_continuation and await_continuation instructions.
1 parent 836e90c commit 812ef34

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

lib/SIL/IR/SILInstruction.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,6 +1646,10 @@ bool SILInstruction::maySuspend() const {
16461646
// await_async_continuation always suspends the current task.
16471647
if (isa<AwaitAsyncContinuationInst>(this))
16481648
return true;
1649+
1650+
// hop_to_executor also may cause a suspension
1651+
if (isa<HopToExecutorInst>(this))
1652+
return true;
16491653

16501654
// Fully applying an async function may suspend the caller.
16511655
if (auto applySite = FullApplySite::isa(const_cast<SILInstruction*>(this))) {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: not --crash %target-sil-opt %s 2>&1 | %FileCheck %s
2+
// REQUIRES: asserts
3+
4+
// CHECK: cannot suspend async task while unawaited continuation is active
5+
6+
sil_stage raw
7+
8+
import Builtin
9+
import Swift
10+
import SwiftShims
11+
import _Concurrency
12+
13+
// hello(_:)
14+
sil hidden [ossa] @$s4main5helloyS2bYaF : $@convention(thin) @async (Bool) -> Bool {
15+
bb0(%0 : $Bool):
16+
debug_value %0 : $Bool, let, name "b", argno 1
17+
%2 = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
18+
%22 = alloc_stack $Bool
19+
%27 = get_async_continuation_addr Bool, %22 : $*Bool
20+
hop_to_executor %2 : $Optional<Builtin.Executor> // <- the bad nested suspension
21+
await_async_continuation %27 : $Builtin.RawUnsafeContinuation, resume bb1
22+
23+
bb1:
24+
dealloc_stack %22 : $*Bool
25+
return %0 : $Bool
26+
}

0 commit comments

Comments
 (0)