Skip to content

Commit efb3c50

Browse files
Merge pull request #11310 from aschwaighofer/irgen_fix_objc_partial_apply_forwarder
IRGen: Fix ObjectiveC partial apply forwarding stub
2 parents dbca173 + ce85f8e commit efb3c50

File tree

3 files changed

+46
-3
lines changed

3 files changed

+46
-3
lines changed

lib/IRGen/GenObjC.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -871,8 +871,8 @@ static llvm::Function *emitObjCPartialApplicationForwarder(IRGenModule &IGM,
871871
// Otherwise, we have a loadable type that can either be passed directly or
872872
// indirectly.
873873
assert(info.getSILStorageType().isObject());
874-
auto &ti =
875-
cast<LoadableTypeInfo>(IGM.getTypeInfo(info.getSILStorageType()));
874+
auto curSILType = info.getSILStorageType();
875+
auto &ti = cast<LoadableTypeInfo>(IGM.getTypeInfo(curSILType));
876876

877877
// Load the indirectly passed parameter.
878878
auto &nativeSchema = ti.nativeParameterValueSchema(IGM);
@@ -881,8 +881,16 @@ static llvm::Function *emitObjCPartialApplicationForwarder(IRGenModule &IGM,
881881
ti.loadAsTake(subIGF, paramAddr, translatedParams);
882882
continue;
883883
}
884+
// Map from the native calling convention into the explosion schema.
885+
auto &nativeParamSchema = ti.nativeParameterValueSchema(IGM);
886+
Explosion nativeParam;
887+
params.transferInto(nativeParam, nativeParamSchema.size());
888+
Explosion nonNativeParam = nativeParamSchema.mapFromNative(
889+
subIGF.IGM, subIGF, nativeParam, curSILType);
890+
assert(nativeParam.empty());
891+
884892
// Pass along the value.
885-
ti.reexplode(subIGF, params, translatedParams);
893+
ti.reexplode(subIGF, nonNativeParam, translatedParams);
886894
}
887895

888896
// Prepare the call to the underlying method.

test/IRGen/Inputs/usr/include/Gizmo.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ struct NSRect {
2323
} size;
2424
};
2525

26+
struct Fob {
27+
unsigned long a;
28+
unsigned b;
29+
unsigned c;
30+
unsigned long d;
31+
} Fob;
32+
2633
typedef long NSInteger;
2734

2835
@interface Gizmo : NSObject
@@ -37,6 +44,7 @@ typedef long NSInteger;
3744
- (struct NSRect) frame;
3845
- (void) setFrame: (struct NSRect) rect;
3946
- (void) frob;
47+
- (void) test: (struct Fob) fob;
4048
+ (void) runce;
4149
@end
4250

test/IRGen/partial_apply_objc.sil

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,30 @@ entry(%c : $Gizmo):
198198
%g = partial_apply %f(%c) : $@convention(thin) Gizmo -> ()
199199
return %g : $@callee_owned () -> ()
200200
}
201+
202+
// CHECK: define internal swiftcc void @_T0Ta.17(i64, i64, i64, %swift.refcounted* swiftself)
203+
// CHECK: [[TMPCOERCE:%.*]] = alloca { i64, i64, i64 }
204+
// CHECK: [[INDIRECTTEMP:%.*]] = alloca %TSC3FobV
205+
// CHECK: [[ADDR:%.*]] = getelementptr inbounds { i64, i64, i64 }, { i64, i64, i64 }* [[TMPCOERCE]], i32 0, i32 0
206+
// CHECK: store i64 %0, i64* [[ADDR]]
207+
// CHECK: [[ADDR:%.]] = getelementptr inbounds { i64, i64, i64 }, { i64, i64, i64 }* [[TMPCOERCE]], i32 0, i32 1
208+
// CHECK: store i64 %1, i64* [[ADDR]]
209+
// CHECK: [[ADDR:%.*]] = getelementptr inbounds { i64, i64, i64 }, { i64, i64, i64 }* [[TMPCOERCE]], i32 0, i32 2
210+
// CHECK: store i64 %2, i64* [[ADDR]]
211+
// CHECK: load i64
212+
// CHECK: load i32
213+
// CHECK: load i32
214+
// CHECK: load i64
215+
// CHECK: store i64
216+
// CHECK: store i32
217+
// CHECK: store i32
218+
// CHECK: store i64
219+
// CHECK: objc_msgSend
220+
// CHECK: ret void
221+
222+
sil @objc_partial_apply_2 : $@convention(thin) Gizmo -> @callee_owned (Fob) -> () {
223+
entry(%c : $Gizmo):
224+
%m = class_method [volatile] %c : $Gizmo, #Gizmo.test!1.foreign : (Gizmo) -> (Fob) -> (), $@convention(objc_method) (Fob, Gizmo) -> ()
225+
%p = partial_apply %m(%c) : $@convention(objc_method) (Fob, Gizmo) -> ()
226+
return %p : $@callee_owned (Fob) -> ()
227+
}

0 commit comments

Comments
 (0)