Skip to content

Commit 70dca91

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 4dbe922 commit 70dca91

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

lib/SILGen/SILGenThunk.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,15 @@ SILFunction *SILGenModule::getOrCreateForeignAsyncCompletionHandlerImplFunction(
399399
continue;
400400
paramIndices.push_back(index);
401401
}
402+
auto blockParamIndex = [paramIndices](unsigned long i) {
403+
// The non-error, non-flag block parameter (formal types of the
404+
// completion handler's arguments) indices are the same as the the
405+
// parameter (lowered types of the completion handler's arguments)
406+
// indices but shifted by 1 corresponding to the fact that the lowered
407+
// completion handler has a block_storage argument but the formal type
408+
// does not.
409+
return paramIndices[i] - 1;
410+
};
402411
if (auto resumeTuple = dyn_cast<TupleType>(resumeType)) {
403412
assert(paramIndices.size() == resumeTuple->getNumElements());
404413
assert(params.size() == resumeTuple->getNumElements()
@@ -412,7 +421,8 @@ SILFunction *SILGenModule::getOrCreateForeignAsyncCompletionHandlerImplFunction(
412421
F->mapTypeIntoContext(resumeTuple.getElementTypes()[i])
413422
->getCanonicalType(),
414423
/*arg*/ params[paramIndices[i]],
415-
/*argFormalType*/ blockParams[i].getParameterType());
424+
/*argFormalType*/
425+
blockParams[blockParamIndex(i)].getParameterType());
416426
}
417427
} else {
418428
assert(paramIndices.size() == 1);
@@ -421,7 +431,8 @@ SILFunction *SILGenModule::getOrCreateForeignAsyncCompletionHandlerImplFunction(
421431
/*destFormalType*/
422432
F->mapTypeIntoContext(resumeType)->getCanonicalType(),
423433
/*arg*/ params[paramIndices[0]],
424-
/*argFormalType*/ blockParams[0].getParameterType());
434+
/*argFormalType*/
435+
blockParams[blockParamIndex(0)].getParameterType());
425436
}
426437

427438
// Resume the continuation with the composed bridged result.

0 commit comments

Comments
 (0)