Skip to content

Commit 26af2d7

Browse files
Merge pull request swiftlang#30516 from aschwaighofer/silgen_fix_assign_by_wrapper_objc_dynamic
SILGen: Fix assign_by_wrapper of ``@objc dynamic`` properties
2 parents 70971b5 + 57c6c59 commit 26af2d7

File tree

2 files changed

+35
-7
lines changed

2 files changed

+35
-7
lines changed

lib/SILGen/SILGenLValue.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,11 +1448,16 @@ namespace {
14481448
SGF.getConstantInfo(SGF.getTypeExpansionContext(), setter);
14491449
SILValue setterFRef;
14501450
if (setter.hasDecl() && setter.getDecl()->isObjCDynamic()) {
1451-
auto methodTy = SILType::getPrimitiveObjectType(
1452-
SGF.SGM.Types.getConstantFunctionType(SGF.getTypeExpansionContext(),
1453-
setter));
1454-
setterFRef = SGF.B.createObjCMethod(
1455-
loc, base.getValue(), setter, methodTy);
1451+
// Emit a thunk we might have to bridge arguments.
1452+
auto foreignSetterThunk = setter.asForeign(false);
1453+
setterFRef =
1454+
SGF.emitDynamicMethodRef(
1455+
loc, foreignSetterThunk,
1456+
SGF.SGM.Types
1457+
.getConstantInfo(SGF.getTypeExpansionContext(), foreignSetterThunk)
1458+
.SILFnType)
1459+
.getValue();
1460+
14561461
} else
14571462
setterFRef = SGF.emitGlobalFunctionRef(loc, setter, setterInfo);
14581463
CanSILFunctionType setterTy = setterFRef->getType().castTo<SILFunctionType>();

test/SILGen/objc_properties.swift

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,13 +270,36 @@ public struct SomeWrapper {
270270
}
271271
}
272272

273+
@propertyWrapper struct W<Value> {
274+
var wrappedValue: Value {
275+
get { return x }
276+
set { }
277+
}
278+
279+
var x: Value
280+
281+
init(wrappedValue: Value) {
282+
x = wrappedValue
283+
}
284+
}
285+
273286
class SomeWrapperTests {
274287
@objc @SomeWrapper dynamic var someWrapper: Int = 0
275288
// CHECK-LABEL: sil hidden [ossa] @$s15objc_properties16SomeWrapperTestsC14testAssignmentyyF
276-
// CHECK: [[M:%.*]] = objc_method %0 : $SomeWrapperTests, #SomeWrapperTests.someWrapper!setter.foreign
277-
// CHECK: [[C:%.*]] = partial_apply [callee_guaranteed] [[M]]({{.*}}) : $@convention(objc_method)
289+
// CHECK: [[M:%.*]] = function_ref @$s15objc_properties16SomeWrapperTestsC04someD0SivsTD
290+
// CHECK: [[C:%.*]] = partial_apply [callee_guaranteed] [[M]]({{.*}})
278291
// CHECK: assign_by_wrapper {{%.*}}: $Int to {{%.*}} : $*SomeWrapper, init {{.*}} : $@callee_guaranteed (Int) -> SomeWrapper, set [[C]] : $@callee_guaranteed (Int) -> ()
279292
func testAssignment() {
280293
someWrapper = 1000
281294
}
295+
296+
@W @objc dynamic var s: String? = nil
297+
// CHECK-LABEL: sil hidden [ossa] @$s15objc_properties16SomeWrapperTestsC16testBridgedValueyySSF
298+
// CHECK: [[M:%.*]] = function_ref @$s15objc_properties16SomeWrapperTestsC1sSSSgvsTD
299+
// CHECK: [[C:%.*]] = partial_apply [callee_guaranteed] [[M]](
300+
// CHECK: assign_by_wrapper {{.*}} : $Optional<String> to {{.*}} : $*W<Optional<String>>, init {{.*}} : $@callee_guaranteed (@owned Optional<String>) -> @owned W<Optional<String>>, set [[C]] : $@callee_guaranteed (@owned Optional<String>) -> ()
301+
// Let's not crash.
302+
func testBridgedValue(_ s: String) {
303+
self.s = s
304+
}
282305
}

0 commit comments

Comments
 (0)