Skip to content

Commit 17e3054

Browse files
authored
Merge pull request swiftlang#79848 from gottesmm/pr-87b605dd36923c565ba5ca391df61dde2d835338
[silgen] Place hop_to_executor emission for an apply within a formal evaluation scope.
2 parents 396e8f0 + 2340dba commit 17e3054

File tree

5 files changed

+48
-9
lines changed

5 files changed

+48
-9
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5809,6 +5809,14 @@ RValue SILGenFunction::emitApply(
58095809
if (implicitActorHopTarget) {
58105810
assert(F.isAsync() && "cannot hop_to_executor in a non-async func!");
58115811

5812+
// We need to scope this strongly to ensure that the lifetime of the loaded
5813+
// executor ends before the apply in case we are passing the executor as an
5814+
// owned parameter to the apply.
5815+
//
5816+
// This can occur in situations where we borrow the executor for
5817+
// hop_to_executor and then pass the executor as an owned isolated parameter
5818+
// to an initializer.
5819+
FormalEvaluationScope hopToExecutorScope(*this);
58125820
SILValue executor;
58135821
switch (*implicitActorHopTarget) {
58145822
case ActorIsolation::ActorInstance:

test/SILGen/async_initializer.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ enum Birb {
142142
// CHECK-LABEL: sil hidden [ossa] @$s12initializers7makeCatyyYaF : $@convention(thin) @async () -> () {
143143
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
144144
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
145-
// CHECK: hop_to_executor {{%[0-9]+}} : $MainActor
145+
// CHECK: hop_to_executor [[BORROWED_EXECUTOR:%[0-9]+]]
146+
// CHECK: end_borrow [[BORROWED_EXECUTOR]]
146147
// CHECK-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(method) (@owned String, @thick Cat.Type) -> @owned Cat
147148
// CHECK: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
148149
// CHECK: } // end sil function '$s12initializers7makeCatyyYaF'
@@ -153,7 +154,8 @@ func makeCat() async {
153154
// CHECK-LABEL: sil hidden [ossa] @$s12initializers7makeDogyyYaF : $@convention(thin) @async () -> () {
154155
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
155156
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
156-
// CHECK: hop_to_executor {{%[0-9]+}} : $MainActor
157+
// CHECK: hop_to_executor [[BORROWED_EXEC:%.*]] :
158+
// CHECK-NEXT: end_borrow [[BORROWED_EXEC]]
157159
// CHECK-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(method) (@owned String, @thin Dog.Type) -> Dog
158160
// CHECK: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
159161
// CHECK: } // end sil function '$s12initializers7makeDogyyYaF'
@@ -164,7 +166,8 @@ func makeDog() async {
164166
// CHECK-LABEL: sil hidden [ossa] @$s12initializers8makeBirbyyYaF : $@convention(thin) @async () -> () {
165167
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
166168
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
167-
// CHECK: hop_to_executor {{%[0-9]+}} : $MainActor
169+
// CHECK: hop_to_executor [[BORROWED_EXEC:%.*]] : $MainActor
170+
// CHECK-NEXT: end_borrow [[BORROWED_EXEC]]
168171
// CHECK-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(method) (@owned String, @thin Birb.Type) -> Birb
169172
// CHECK: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
170173
// CHECK: } // end sil function '$s12initializers8makeBirbyyYaF'

test/SILGen/hop_to_executor.swift

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,9 +270,9 @@ struct BlueActor {
270270
// CHECK: [[R:%[0-9]+]] = apply [[GETTER]]([[REDMT]]) : $@convention(method) (@thin RedActor.Type) -> @owned RedActorImpl
271271
// CHECK: [[REDEXE:%[0-9]+]] = begin_borrow [[R]] : $RedActorImpl
272272
// CHECK: hop_to_executor [[REDEXE]] : $RedActorImpl
273+
// CHECK-NEXT: end_borrow [[REDEXE]]
273274
// ---- now invoke redFn, hop back to Blue, and clean-up ----
274275
// CHECK-NEXT: {{%[0-9]+}} = apply [[CALLEE]]([[ARG]]) : $@convention(thin) (Int) -> ()
275-
// CHECK-NEXT: end_borrow [[REDEXE]] : $RedActorImpl
276276
// CHECK-NEXT: destroy_value [[R]] : $RedActorImpl
277277
// CHECK-NEXT: hop_to_executor [[BLUEEXE]] : $BlueActorImpl
278278
// CHECK: end_borrow [[BLUEEXE]] : $BlueActorImpl
@@ -287,8 +287,8 @@ struct BlueActor {
287287
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] :
288288
// CHECK: [[BORROW:%[0-9]+]] = begin_borrow {{%[0-9]+}} : $RedActorImpl
289289
// CHECK-NEXT: hop_to_executor [[BORROW]] : $RedActorImpl
290-
// CHECK-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}) : $@convention(thin) (Int) -> ()
291290
// CHECK-NEXT: end_borrow [[BORROW]] : $RedActorImpl
291+
// CHECK-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}) : $@convention(thin) (Int) -> ()
292292
// CHECK-NEXT: destroy_value
293293
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]]
294294
// CHECK: } // end sil function '$s4test20unspecifiedAsyncFuncyyYaF'
@@ -315,6 +315,7 @@ func anotherUnspecifiedAsyncFunc(_ red : RedActorImpl) async {
315315
// CHECK: hop_to_executor [[GENERIC_EXEC]] :
316316
// CHECK: function_ref @$s4test8RedActorV6sharedAA0bC4ImplCvgZ
317317
// CHECK: hop_to_executor [[RED:%[0-9]+]] : $RedActorImpl
318+
// CHECK-NEXT: end_borrow [[RED]]
318319
// CHECK-NEXT: begin_borrow
319320
// CHECK-NEXT: apply
320321
// CHECK: hop_to_executor [[GENERIC_EXEC:%[0-9]+]] : $Optional<Builtin.Executor>
@@ -464,10 +465,37 @@ func asyncWithUnsafeInheritance_hopback() async {
464465
// CHECK-NEXT: [[ACTOR:%.*]] = apply [[ACTOR_GETTER]]([[METATYPE]])
465466
// CHECK-NEXT: [[BORROWED_ACTOR:%.*]] = begin_borrow [[ACTOR]]
466467
// CHECK-NEXT: hop_to_executor [[BORROWED_ACTOR]]
467-
// CHECK-NEXT: apply [[FN]]({{%.*}})
468468
// CHECK-NEXT: end_borrow [[BORROWED_ACTOR]]
469+
// CHECK-NEXT: apply [[FN]]({{%.*}})
469470
// CHECK-NEXT: destroy_value [[ACTOR]]
470471
// CHECK-NEXT: tuple
471472
// CHECK-NEXT: return
472473
await redFn(0)
473474
}
475+
476+
// Previously we would break Ownership SSA when passing a below since when we
477+
// emitted the hop_to_executor, we would unnecessarily borrow a over the entire
478+
// apply (we only needed it to call hop_to_executor). This would cause an OSSA
479+
// violation since we are going to consume it as part of calling Klass's
480+
// initializer.
481+
482+
// CHECK-LABEL: sil hidden [ossa] @$s4test40validateHopToExecutorLifetimeShortEnoughyyYaF : $@convention(thin) @async () -> () {
483+
// CHECK: hop_to_executor %0
484+
// CHECK: [[ACTOR:%.*]] = init_existential_ref {{%.*}}
485+
// CHECK: [[INIT_FN:%.*]] = function_ref @$s4test40validateHopToExecutorLifetimeShortEnoughyyYaF5KlassL_C2onADScA_pYi_tcfC : $@convention(method) (@sil_isolated @owned any Actor, @thick Klass.Type) -> @owned Klass
486+
// CHECK: [[BORROW:%.*]] = begin_borrow [[ACTOR]]
487+
// CHECK: hop_to_executor [[BORROW]]
488+
// CHECK: end_borrow [[BORROW]]
489+
// CHECK: apply [[INIT_FN]]([[ACTOR]],
490+
// CHECK: hop_to_executor %0
491+
// CHECK: } // end sil function '$s4test40validateHopToExecutorLifetimeShortEnoughyyYaF'
492+
func validateHopToExecutorLifetimeShortEnough() async {
493+
class Klass {
494+
init(
495+
on isolation: isolated Actor,
496+
) { }
497+
}
498+
499+
let a = MyActor()
500+
_ = await Klass(on: a)
501+
}

test/SILGen/hop_to_executor_async_prop.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ func accessSweaterOfSweater(cat : Cat) async -> Sweater {
122122
// CHECK: [[GLOBAL_CAT:%[0-9]+]] = begin_borrow [[GLOBAL_CAT_REF]] : $Cat
123123

124124
// CHECK: hop_to_executor [[GLOBAL_CAT]] : $Cat
125-
// CHECK: [[THE_STRING:%[0-9]+]] = apply [[GETTER]]([[CAT]]) : $@convention(method) (@guaranteed Cat) -> @owned String
126125
// CHECK: end_borrow [[GLOBAL_CAT]] : $Cat
126+
// CHECK: [[THE_STRING:%[0-9]+]] = apply [[GETTER]]([[CAT]]) : $@convention(method) (@guaranteed Cat) -> @owned String
127127
// CHECK: destroy_value [[GLOBAL_CAT_REF]] : $Cat
128128
// CHECK: hop_to_executor [[GENERIC_EXEC]]
129129
// CHECK: return [[THE_STRING]] : $String

test/SILGen/toplevel_globalactorvars.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ await printFromMyActor(value: a)
6565
// CHECK: [[PRINTFROMMYACTOR_FUNC:%[0-9]+]] = function_ref @$s24toplevel_globalactorvars16printFromMyActor5valueySi_tF
6666
// CHECK: [[ACTORREF:%[0-9]+]] = begin_borrow {{%[0-9]+}} : $MyActorImpl
6767
// CHECK: hop_to_executor [[ACTORREF]] : $MyActorImpl
68-
// CHECK: {{%[0-9]+}} = apply [[PRINTFROMMYACTOR_FUNC]]([[AGLOBAL]])
6968
// CHECK: end_borrow [[ACTORREF]]
69+
// CHECK: {{%[0-9]+}} = apply [[PRINTFROMMYACTOR_FUNC]]([[AGLOBAL]])
7070
// CHECK: hop_to_executor [[MAIN_OPTIONAL]]
7171

7272
if a < 10 {
@@ -119,7 +119,7 @@ if a < 10 {
119119
// CHECK: [[PRINTFROMMYACTOR_FUNC:%[0-9]+]] = function_ref @$s24toplevel_globalactorvars16printFromMyActor5valueySi_tF
120120
// CHECK: [[ACTORREF:%[0-9]+]] = begin_borrow {{%[0-9]+}} : $MyActorImpl
121121
// CHECK: hop_to_executor [[ACTORREF]] : $MyActorImpl
122-
// CHECK: {{%[0-9]+}} = apply [[PRINTFROMMYACTOR_FUNC]]([[AGLOBAL]])
123122
// CHECK: end_borrow [[ACTORREF]]
123+
// CHECK: {{%[0-9]+}} = apply [[PRINTFROMMYACTOR_FUNC]]([[AGLOBAL]])
124124
// CHECK: hop_to_executor [[MAIN_OPTIONAL]]
125125
}

0 commit comments

Comments
 (0)