Skip to content

Commit cef64c9

Browse files
committed
[SILGen] Fixed handler formal arg type indexing.
In the synthesized completion handler that is passed to ObjC methods that are called as async, the formal type of each argument is the corresponding parameter of the formal type of the block. The non-error, non-index arguments need to be prepared so that they can be used to fulfill the continuation; the lambda which does that preparation for each such argument takes the formal type of that argument. As such, the call to that lambda needs to pass the type of the corresponding parameter of the formal type of the block to that lambda. Doing so entails skipping over the error and flag parameters if they appear before some of the non-error, non-index arguments. Previously, no parameters were skipped over. Consequently, when an error or flag argument preceded one of the non-error, non-index arguments, the wrong formal type was passed to the preparation lambda. Here, that is fixed by passing the correct index. The to-be-used indices for the formal block parameters are the same as the to-be-used indices for the lowered block parameters minus one reflecting the fact that the lowered block always has an initial block_storage parameter as the first argument which the formal type never has. rdar://81617749
1 parent 6eb4f2c commit cef64c9

File tree

4 files changed

+620
-2
lines changed

4 files changed

+620
-2
lines changed

lib/SILGen/SILGenThunk.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,15 @@ SILFunction *SILGenModule::getOrCreateForeignAsyncCompletionHandlerImplFunction(
408408
continue;
409409
paramIndices.push_back(index);
410410
}
411+
auto blockParamIndex = [paramIndices](unsigned long i) {
412+
// The non-error, non-flag block parameter (formal types of the
413+
// completion handler's arguments) indices are the same as the the
414+
// parameter (lowered types of the completion handler's arguments)
415+
// indices but shifted by 1 corresponding to the fact that the lowered
416+
// completion handler has a block_storage argument but the formal type
417+
// does not.
418+
return paramIndices[i] - 1;
419+
};
411420
if (auto resumeTuple = dyn_cast<TupleType>(resumeType)) {
412421
assert(paramIndices.size() == resumeTuple->getNumElements());
413422
assert(params.size() == resumeTuple->getNumElements()
@@ -421,7 +430,8 @@ SILFunction *SILGenModule::getOrCreateForeignAsyncCompletionHandlerImplFunction(
421430
F->mapTypeIntoContext(resumeTuple.getElementTypes()[i])
422431
->getCanonicalType(),
423432
/*arg*/ params[paramIndices[i]],
424-
/*argFormalType*/ blockParams[i].getParameterType());
433+
/*argFormalType*/
434+
blockParams[blockParamIndex(i)].getParameterType());
425435
}
426436
} else {
427437
assert(paramIndices.size() == 1);
@@ -430,7 +440,8 @@ SILFunction *SILGenModule::getOrCreateForeignAsyncCompletionHandlerImplFunction(
430440
/*destFormalType*/
431441
F->mapTypeIntoContext(resumeType)->getCanonicalType(),
432442
/*arg*/ params[paramIndices[0]],
433-
/*argFormalType*/ blockParams[0].getParameterType());
443+
/*argFormalType*/
444+
blockParams[blockParamIndex(0)].getParameterType());
434445
}
435446

436447
// Resume the continuation with the composed bridged result.
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#include <Foundation/Foundation.h>
2+
3+
#pragma clang assume_nonnull begin
4+
5+
typedef void (^CompletionHandler)(void);
6+
7+
@interface PFXObject : NSObject
8+
- (void)performSingleFlaggy1WithCompletionHandler:
9+
(void (^)(BOOL, CompletionHandler _Nullable))completionHandler
10+
__attribute__((swift_async_error(zero_argument, 1)));
11+
- (void)performSingleFlaggy2WithCompletionHandler:
12+
(void (^)(CompletionHandler _Nullable, BOOL))completionHandler
13+
__attribute__((swift_async_error(zero_argument, 2)));
14+
15+
- (void)performSingleErrory1WithCompletionHandler:
16+
(void (^)(NSError *_Nullable,
17+
CompletionHandler _Nullable))completionHandler;
18+
- (void)performSingleErrory2WithCompletionHandler:
19+
(void (^)(CompletionHandler _Nullable,
20+
NSError *_Nullable))completionHandler;
21+
22+
- (void)performSingleBothy12WithCompletionHandler:
23+
(void (^)(NSError *_Nullable, BOOL,
24+
CompletionHandler _Nullable))completionHandler
25+
__attribute__((swift_async_error(zero_argument, 2)));
26+
- (void)performSingleBothy13WithCompletionHandler:
27+
(void (^)(NSError *_Nullable, CompletionHandler _Nullable,
28+
BOOL))completionHandler
29+
__attribute__((swift_async_error(zero_argument, 3)));
30+
- (void)performSingleBothy21WithCompletionHandler:
31+
(void (^)(BOOL, NSError *_Nullable,
32+
CompletionHandler _Nullable))completionHandler
33+
__attribute__((swift_async_error(zero_argument, 1)));
34+
- (void)performSingleBothy23WithCompletionHandler:
35+
(void (^)(CompletionHandler _Nullable, NSError *_Nullable,
36+
BOOL))completionHandler
37+
__attribute__((swift_async_error(zero_argument, 3)));
38+
- (void)performSingleBothy31WithCompletionHandler:
39+
(void (^)(BOOL, CompletionHandler _Nullable,
40+
NSError *_Nullable))completionHandler
41+
__attribute__((swift_async_error(zero_argument, 1)));
42+
- (void)performSingleBothy32WithCompletionHandler:
43+
(void (^)(CompletionHandler _Nullable, BOOL,
44+
NSError *_Nullable))completionHandler
45+
__attribute__((swift_async_error(zero_argument, 2)));
46+
47+
- (void)performDoubleFlaggy1WithCompletionHandler:
48+
(void (^)(BOOL, CompletionHandler _Nullable,
49+
CompletionHandler _Nullable))completionHandler
50+
__attribute__((swift_async_error(zero_argument, 1)));
51+
- (void)performDoubleFlaggy2WithCompletionHandler:
52+
(void (^)(CompletionHandler _Nullable, BOOL,
53+
CompletionHandler _Nullable))completionHandler
54+
__attribute__((swift_async_error(zero_argument, 2)));
55+
- (void)performDoubleFlaggy3WithCompletionHandler:
56+
(void (^)(CompletionHandler _Nullable, CompletionHandler _Nullable,
57+
BOOL))completionHandler
58+
__attribute__((swift_async_error(zero_argument, 3)));
59+
60+
- (void)performDoubleErrory1WithCompletionHandler:
61+
(void (^)(NSError *_Nullable, CompletionHandler _Nullable,
62+
CompletionHandler _Nullable))completionHandler;
63+
- (void)performDoubleErrory2WithCompletionHandler:
64+
(void (^)(CompletionHandler _Nullable, NSError *_Nullable,
65+
CompletionHandler _Nullable))completionHandler;
66+
- (void)performDoubleErrory3WithCompletionHandler:
67+
(void (^)(CompletionHandler _Nullable, CompletionHandler _Nullable,
68+
NSError *_Nullable))completionHandler;
69+
70+
- (void)performDoubleBothy12WithCompletionHandler:
71+
(void (^)(NSError *_Nullable, BOOL, CompletionHandler _Nullable,
72+
CompletionHandler _Nullable))completionHandler
73+
__attribute__((swift_async_error(zero_argument, 2)));
74+
- (void)performDoubleBothy13WithCompletionHandler:
75+
(void (^)(NSError *_Nullable, CompletionHandler _Nullable, BOOL,
76+
CompletionHandler _Nullable))completionHandler
77+
__attribute__((swift_async_error(zero_argument, 3)));
78+
- (void)performDoubleBothy14WithCompletionHandler:
79+
(void (^)(NSError *_Nullable, CompletionHandler _Nullable,
80+
CompletionHandler _Nullable, BOOL))completionHandler
81+
__attribute__((swift_async_error(zero_argument, 4)));
82+
83+
- (void)performDoubleBothy21WithCompletionHandler:
84+
(void (^)(BOOL, NSError *_Nullable, CompletionHandler _Nullable,
85+
CompletionHandler _Nullable))completionHandler
86+
__attribute__((swift_async_error(zero_argument, 1)));
87+
- (void)performDoubleBothy23WithCompletionHandler:
88+
(void (^)(CompletionHandler _Nullable, NSError *_Nullable, BOOL,
89+
CompletionHandler _Nullable))completionHandler
90+
__attribute__((swift_async_error(zero_argument, 3)));
91+
- (void)performDoubleBothy24WithCompletionHandler:
92+
(void (^)(CompletionHandler _Nullable, NSError *_Nullable,
93+
CompletionHandler _Nullable, BOOL))completionHandler
94+
__attribute__((swift_async_error(zero_argument, 4)));
95+
96+
- (void)performDoubleBothy31WithCompletionHandler:
97+
(void (^)(BOOL, CompletionHandler _Nullable, NSError *_Nullable,
98+
CompletionHandler _Nullable))completionHandler
99+
__attribute__((swift_async_error(zero_argument, 1)));
100+
- (void)performDoubleBothy32WithCompletionHandler:
101+
(void (^)(CompletionHandler _Nullable, BOOL, NSError *_Nullable,
102+
CompletionHandler _Nullable))completionHandler
103+
__attribute__((swift_async_error(zero_argument, 2)));
104+
- (void)performDoubleBothy34WithCompletionHandler:
105+
(void (^)(CompletionHandler _Nullable, CompletionHandler _Nullable,
106+
NSError *_Nullable, BOOL))completionHandler
107+
__attribute__((swift_async_error(zero_argument, 4)));
108+
109+
- (void)performDoubleBothy41WithCompletionHandler:
110+
(void (^)(BOOL, CompletionHandler _Nullable, CompletionHandler _Nullable,
111+
NSError *_Nullable))completionHandler
112+
__attribute__((swift_async_error(zero_argument, 1)));
113+
- (void)performDoubleBothy42WithCompletionHandler:
114+
(void (^)(CompletionHandler _Nullable, BOOL, CompletionHandler _Nullable,
115+
NSError *_Nullable))completionHandler
116+
__attribute__((swift_async_error(zero_argument, 2)));
117+
- (void)performDoubleBothy43WithCompletionHandler:
118+
(void (^)(CompletionHandler _Nullable, CompletionHandler _Nullable, BOOL,
119+
NSError *_Nullable))completionHandler
120+
__attribute__((swift_async_error(zero_argument, 3)));
121+
@end
122+
123+
#pragma clang assume_nonnull end

0 commit comments

Comments
 (0)