Skip to content

Commit 5df0978

Browse files
committed
[sending] Fix recent alloc_stack as indirect result isolation inference to infer disconnected if the alloc stack is used as a sending indirect result.
I also fixed an issue that I found where we were not substituting SILResultInfo flags which was causing us to drop when substituting sil_sending. I added a SILVerifier check to make sure that we do not break this again. (cherry picked from commit c7124e4)
1 parent 36ac58f commit 5df0978

File tree

5 files changed

+47
-4
lines changed

5 files changed

+47
-4
lines changed

lib/SIL/IR/SILTypeSubstitution.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,8 @@ class SILTypeSubstituter :
298298
}
299299

300300
SILResultInfo substInterface(SILResultInfo orig) {
301-
return SILResultInfo(visit(orig.getInterfaceType()), orig.getConvention());
301+
return SILResultInfo(visit(orig.getInterfaceType()), orig.getConvention(),
302+
orig.getOptions());
302303
}
303304

304305
SILYieldInfo substInterface(SILYieldInfo orig) {

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,6 +1943,13 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
19431943
}
19441944
}
19451945
}
1946+
1947+
// Make sure that our subst and orig callee type agree on having sending
1948+
// results or not.
1949+
require(site.getOrigCalleeType()->hasSendingResult() ==
1950+
site.getSubstCalleeType()->hasSendingResult(),
1951+
"Callee's orig and subst callee type must have the same sending "
1952+
"result");
19461953
}
19471954

19481955
void checkApplyInst(ApplyInst *AI) {

lib/SILOptimizer/Analysis/RegionAnalysis.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,10 +1926,10 @@ class PartitionOpTranslator {
19261926
isolationInfo);
19271927
}
19281928

1929-
// If our result is transferring, then pass in empty as our results and then
1930-
// perform assign fresh.
1929+
// If our result is transferring, then pass in empty as our results, no
1930+
// override isolation, then perform assign fresh.
19311931
ArrayRef<SILValue> empty;
1932-
translateSILMultiAssign(empty, nonTransferringParameters, isolationInfo);
1932+
translateSILMultiAssign(empty, nonTransferringParameters, {});
19331933
for (SILValue result : applyResults) {
19341934
if (auto value = tryToTrackValue(result)) {
19351935
builder.addAssignFresh(value->getRepresentative().getValue());

lib/SILOptimizer/Utils/SILIsolationInfo.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,15 @@ inferIsolationInfoForTempAllocStack(AllocStackInst *asi) {
221221

222222
// Otherwise, lets see if we had a same block indirect result.
223223
if (state.sameBlockIndirectResultUses) {
224+
// Check if this indirect result has a sending result. In such a case, we
225+
// always return disconnected.
226+
if (auto fas =
227+
FullApplySite::isa(state.sameBlockIndirectResultUses->getUser())) {
228+
if (fas.getSubstCalleeType()->hasSendingResult())
229+
return SILIsolationInfo::getDisconnected(
230+
false /*is unsafe non isolated*/);
231+
}
232+
224233
// If we do not have any writes in between the alloc stack and the
225234
// initializer, then we have a good target. Otherwise, we just return
226235
// AssignFresh.
@@ -338,6 +347,11 @@ inferIsolationInfoForTempAllocStack(AllocStackInst *asi) {
338347
// At this point, we know that we have a single indirect result use that
339348
// dominates all writes and other indirect result uses. We can say that our
340349
// alloc_stack temporary is that indirect result use's isolation.
350+
if (auto fas = FullApplySite::isa(targetOperand->getUser())) {
351+
if (fas.getSubstCalleeType()->hasSendingResult())
352+
return SILIsolationInfo::getDisconnected(
353+
false /*is unsafe non isolated*/);
354+
}
341355
return SILIsolationInfo::get(targetOperand->getUser());
342356
}
343357

test/Concurrency/transfernonsendable.sil

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,3 +375,24 @@ bb0(%0 : @guaranteed $Self):
375375
return %9999 : $()
376376
}
377377

378+
sil @closureForCheckedContinuation : $@convention(thin) <τ_0_0> (@in_guaranteed CheckedContinuation<τ_0_0, Never>) -> ()
379+
sil @withCheckedContinuation : $@convention(thin) @async <τ_0_0> (@sil_isolated @guaranteed Optional<any Actor>, @guaranteed @noescape @callee_guaranteed <τ_0_0> (@in_guaranteed CheckedContinuation<τ_0_0, Never>) -> ()) -> @sil_sending @out τ_0_0
380+
381+
// We shouldn't emit any error here due to sil_sending.
382+
sil [ossa] @sending_result_from_callee : $@convention(thin) @async () -> () {
383+
bb0:
384+
%0 = alloc_stack $NonSendableKlass
385+
%1 = function_ref @closureForCheckedContinuation : $@convention(thin) <τ_0_0> (@in_guaranteed CheckedContinuation<τ_0_0, Never>) -> ()
386+
%1a = thin_to_thick_function %1 : $@convention(thin) <τ_0_0> (@in_guaranteed CheckedContinuation<τ_0_0, Never>) -> () to $@noescape @callee_guaranteed <τ_0_0> (@in_guaranteed CheckedContinuation<τ_0_0, Never>) -> ()
387+
%2 = enum $Optional<any Actor>, #Optional.none!enumelt
388+
%3 = function_ref @withCheckedContinuation : $@convention(thin) @async <τ_0_0> (@sil_isolated @guaranteed Optional<any Actor>, @guaranteed @noescape @callee_guaranteed <τ_0_0> (@in_guaranteed CheckedContinuation<τ_0_0, Never>) -> ()) -> @sil_sending @out τ_0_0
389+
apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %3<NonSendableKlass>(%0, %2, %1a) : $@convention(thin) @async <τ_0_0> (@sil_isolated @guaranteed Optional<any Actor>, @guaranteed @noescape @callee_guaranteed <τ_0_0> (@in_guaranteed CheckedContinuation<τ_0_0, Never>) -> ()) -> @sil_sending @out τ_0_0
390+
391+
%f = function_ref @transferIndirect : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
392+
apply [caller_isolation=nonisolated] [callee_isolation=actor_instance] %f<NonSendableKlass>(%0) : $@convention(thin) @async <τ_0_0> (@in_guaranteed τ_0_0) -> ()
393+
394+
destroy_addr %0 : $*NonSendableKlass
395+
dealloc_stack %0 : $*NonSendableKlass
396+
%9999 = tuple ()
397+
return %9999 : $()
398+
}

0 commit comments

Comments
 (0)