Skip to content

Commit d0b0de9

Browse files
committed
Fix emitDynamicAlloca of an partial_apply [stack] in a coroutine that reuses heap object as context
1 parent a0b67c6 commit d0b0de9

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

lib/IRGen/GenOpaque.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -555,15 +555,17 @@ StackAddress IRGenFunction::emitDynamicAlloca(llvm::Type *eltTy,
555555
/// location before the dynamic alloca's call.
556556
void IRGenFunction::emitDeallocateDynamicAlloca(StackAddress address) {
557557
// In coroutines, unconditionally call llvm.coro.alloca.free.
558-
if (isCoroutine()) {
558+
// Except if the address is invalid, this happens when this is a StackAddress
559+
// for a partial_apply [stack] that did not need a context object on the
560+
// stack.
561+
if (isCoroutine() && address.getAddress().isValid()) {
559562
auto allocToken = address.getExtraInfo();
560563
assert(allocToken && "dynamic alloca in coroutine without alloc token?");
561564
auto freeFn = llvm::Intrinsic::getDeclaration(
562565
&IGM.Module, llvm::Intrinsic::ID::coro_alloca_free);
563566
Builder.CreateCall(freeFn, allocToken);
564567
return;
565568
}
566-
567569
// Otherwise, call llvm.stackrestore if an address was saved.
568570
auto savedSP = address.getExtraInfo();
569571
if (savedSP == nullptr)
@@ -1444,4 +1446,4 @@ void TypeInfo::storeExtraInhabitantTagDynamic(IRGenFunction &IGF,
14441446
} else {
14451447
storeEnumTagSinglePayload(IGF, tag, tag, address, T, isOutlined);
14461448
}
1447-
}
1449+
}

test/IRGen/partial_apply.sil

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,4 +602,27 @@ bb0(%0 : $*A2<A3>):
602602
return %5 : $@callee_guaranteed () -> (@owned A1, @error Error)
603603
}
604604

605+
sil @capture_class : $@convention(thin) (@guaranteed A3) -> ()
606+
607+
// CHECK: define swiftcc i8* @partial_apply_stack_in_coroutine(i8* {{.*}}, %T13partial_apply2A3C*)
608+
// CHECK: entry:
609+
// CHECK: [[CLOSURE_CONTEXT:%.*]] = bitcast %T13partial_apply2A3C* %1 to %swift.opaque*
610+
// CHECK: [[CONTEXT:%.*]] = bitcast %swift.opaque* [[CLOSURE_CONTEXT]] to %swift.refcounted*
611+
// CHECK: call swiftcc void @"$s13capture_classTA"(%swift.refcounted* swiftself [[CONTEXT]])
612+
sil @partial_apply_stack_in_coroutine : $@yield_once (@owned A3) -> () {
613+
entry(%0: $A3):
614+
%f = function_ref @capture_class : $@convention(thin) (@guaranteed A3) -> ()
615+
%p = partial_apply [callee_guaranteed] [on_stack] %f(%0) : $@convention(thin) (@guaranteed A3) -> ()
616+
apply %p() : $@noescape @callee_guaranteed () -> ()
617+
dealloc_stack %p : $@noescape @callee_guaranteed () -> ()
618+
%1000 = integer_literal $Builtin.Int32, 1000
619+
yield (), resume resume, unwind unwind
620+
621+
resume:
622+
%ret = tuple ()
623+
return %ret : $()
624+
625+
unwind:
626+
unwind
627+
}
605628
sil_vtable A3 {}

0 commit comments

Comments
 (0)