Skip to content

Commit 1046a03

Browse files
committed
[concurrency] When calling an imported async objc function using continuations, use merge_isolation_region to tie the block storage and the resume buffer into one region.
This ensures that if the block has an @out return value that the return value is considered to be affected by the actual call of the block. Before b/c we smuggled the value through a Sendable continuation, we would lose the connection in between the block and that result. rdar://131422332
1 parent a707691 commit 1046a03

File tree

3 files changed

+24
-0
lines changed

3 files changed

+24
-0
lines changed

lib/SILGen/ResultPlan.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,12 @@ class ForeignAsyncInitializationPlan final : public ResultPlan {
806806
std::tie(blockStorage, blockStorageTy, continuationTy) =
807807
emitBlockStorage(SGF, loc, throws);
808808

809+
// Add a merge_isolation_region from the continuation result buffer
810+
// (resumeBuf) onto the block storage so it is in the same region as the
811+
// block storage despite the intervening Sendable continuation wrapping that
812+
// disguises this fact from the region isolation checker.
813+
SGF.B.createMergeIsolationRegion(loc, {blockStorage, resumeBuf});
814+
809815
// Get the block invocation function for the given completion block type.
810816
auto completionHandlerIndex = calleeTypeInfo.foreign.async
811817
->completionHandlerParamIndex();

test/Concurrency/Inputs/transfernonsendable_objc.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,15 @@
99
@protocol MySession <NSObject>
1010
- (void)endSession;
1111
@end
12+
13+
typedef NSString *MyStringEnum NS_EXTENSIBLE_STRING_ENUM;
14+
15+
@interface MyAssetTrack : NSObject
16+
@end
17+
18+
@interface MyAsset : NSObject
19+
20+
- (void)loadTracksWithStringEnum:(MyStringEnum)stringEnum completionHandler:(void (^)(NSArray<MyAssetTrack *> * _Nullable, NSError * _Nullable)) completionHandler;
21+
22+
@end
23+

test/Concurrency/transfernonsendable_objc.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,9 @@ actor MyActor {
2525
defer { session?.end() }
2626
}
2727
}
28+
29+
extension MyAsset {
30+
func continuationResultTiedToContinuation(withStringEnum stringEnum: MyStringEnum) async throws -> sending [MyAssetTrack] {
31+
try await loadTracks(withStringEnum: stringEnum)
32+
}
33+
}

0 commit comments

Comments
 (0)