Skip to content

Commit 5910d82

Browse files
authored
Merge pull request #34456 from slavapestov/foreign-to-native-inout-self
SILGen: Fix assertion failure when emitting foreign-to-native thunk for a method with inout 'self'
2 parents 2bcc74c + 51c1fa9 commit 5910d82

File tree

3 files changed

+38
-6
lines changed

3 files changed

+38
-6
lines changed

lib/SILGen/SILGenBridging.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -336,10 +336,17 @@ static ManagedValue emitManagedParameter(SILGenFunction &SGF, SILLocation loc,
336336

337337
/// Get the type of each parameter, filtering out empty tuples.
338338
static SmallVector<CanType, 8>
339-
getParameterTypes(AnyFunctionType::CanParamArrayRef params) {
339+
getParameterTypes(AnyFunctionType::CanParamArrayRef params,
340+
bool hasSelfParam=false) {
340341
SmallVector<CanType, 8> results;
341-
for (auto param : params) {
342-
assert(!param.isInOut() && !param.isVariadic());
342+
for (auto n : indices(params)) {
343+
bool isSelf = (hasSelfParam ? n == params.size() - 1 : false);
344+
345+
const auto &param = params[n];
346+
assert(isSelf || !param.isInOut() &&
347+
"Only the 'self' parameter can be inout in a bridging thunk");
348+
assert(!param.isVariadic());
349+
343350
if (param.getPlainType()->isVoid())
344351
continue;
345352
results.push_back(param.getPlainType());
@@ -1723,10 +1730,11 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) {
17231730
};
17241731

17251732
{
1733+
bool hasSelfParam = fd->hasImplicitSelfDecl();
17261734
auto foreignFormalParams =
1727-
getParameterTypes(foreignCI.LoweredType.getParams());
1735+
getParameterTypes(foreignCI.LoweredType.getParams(), hasSelfParam);
17281736
auto nativeFormalParams =
1729-
getParameterTypes(nativeCI.LoweredType.getParams());
1737+
getParameterTypes(nativeCI.LoweredType.getParams(), hasSelfParam);
17301738

17311739
for (unsigned nativeParamIndex : indices(params)) {
17321740
// Bring the parameter to +1.
@@ -1762,7 +1770,7 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) {
17621770

17631771
maybeAddForeignErrorArg();
17641772

1765-
bool isSelf = nativeParamIndex == params.size() - 1;
1773+
bool isSelf = (hasSelfParam && nativeParamIndex == params.size() - 1);
17661774

17671775
if (memberStatus.isInstance()) {
17681776
// Leave space for `self` to be filled in later.
@@ -1787,6 +1795,12 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) {
17871795
F.mapTypeIntoContext(foreignFormalParams[nativeParamIndex])
17881796
->getCanonicalType();
17891797

1798+
if (isSelf) {
1799+
assert(!nativeCI.LoweredType.getParams()[nativeParamIndex].isInOut() ||
1800+
nativeFormalType == foreignFormalType &&
1801+
"Cannot bridge 'self' parameter if passed inout");
1802+
}
1803+
17901804
auto foreignParam = foreignFnTy->getParameters()[foreignArgIndex++];
17911805
SILType foreignLoweredTy =
17921806
F.mapTypeIntoContext(foreignParam.getSILStorageType(
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
typedef struct {} MyIterator __attribute__((swift_name("MyIterator")));
2+
3+
void MyIteratorNext(MyIterator *self) __attribute__((swift_name("MyIterator.next(self:)")));
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %target-swift-frontend -emit-silgen %s -import-objc-header %S/Inputs/foreign_to_native_inout_self_helper.h | %FileCheck %s
2+
3+
protocol FakeIterator {
4+
mutating func next()
5+
}
6+
7+
extension MyIterator : FakeIterator {}
8+
9+
// CHECK-LABEL: sil shared [serializable] [thunk] [ossa] @$sSo10MyIteratora4nextyyFTO : $@convention(method) (@inout MyIterator) -> () {
10+
// CHECK: bb0(%0 : $*MyIterator):
11+
// CHECK: [[FN:%.*]] = function_ref @MyIteratorNext : $@convention(c) (@inout MyIterator) -> ()
12+
// CHECK: apply [[FN]](%0) : $@convention(c) (@inout MyIterator) -> ()
13+
// CHECK: [[RESULT:%.*]] = tuple ()
14+
// CHECK: return [[RESULT]] : $()
15+
// CHECK: }

0 commit comments

Comments
 (0)