Skip to content

Commit dbddb0d

Browse files
Merge pull request swiftlang#27516 from aschwaighofer/silgen_fix_assignment_property_wrapper_objc_dynamic
SILGen: Fix setting variables with property wrappers marked objc dynamic
2 parents b32e82c + e0ce37e commit dbddb0d

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

lib/SILGen/SILGenLValue.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1430,7 +1430,14 @@ namespace {
14301430

14311431
// Create the allocating setter function. It captures the base address.
14321432
auto setterInfo = SGF.getConstantInfo(setter);
1433-
SILValue setterFRef = SGF.emitGlobalFunctionRef(loc, setter, setterInfo);
1433+
SILValue setterFRef;
1434+
if (setter.hasDecl() && setter.getDecl()->isObjCDynamic()) {
1435+
auto methodTy = SILType::getPrimitiveObjectType(
1436+
SGF.SGM.Types.getConstantFunctionType(setter));
1437+
setterFRef = SGF.B.createObjCMethod(
1438+
loc, base.getValue(), setter, methodTy);
1439+
} else
1440+
setterFRef = SGF.emitGlobalFunctionRef(loc, setter, setterInfo);
14341441
CanSILFunctionType setterTy = setterFRef->getType().castTo<SILFunctionType>();
14351442
SILFunctionConventions setterConv(setterTy, SGF.SGM.M);
14361443

test/IRGen/objc_properties.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,30 @@ class Class17127126 {
7878
static var sharedInstance: AnyObject { get set }
7979
}
8080

81+
@propertyWrapper
82+
public struct SomeWrapper {
83+
private var value: Int
84+
85+
86+
public init(wrappedValue: Int) {
87+
value = wrappedValue
88+
}
89+
90+
91+
public var wrappedValue: Int {
92+
get { value }
93+
set { value = newValue }
94+
}
95+
}
96+
97+
class SomeWrapperTests {
98+
@objc @SomeWrapper dynamic var someWrapper: Int = 0
99+
100+
func testAssignment() {
101+
// This used to crash irgen.
102+
someWrapper = 1000
103+
}
104+
}
81105
// CHECK-NEW: [[SHARED_NAME:@.*]] = private unnamed_addr constant [11 x i8] c"sharedProp\00"
82106
// CHECK-NEW: [[SHARED_ATTRS:@.*]] = private unnamed_addr constant [5 x i8] c"Tq,N\00"
83107

test/SILGen/objc_properties.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,3 +253,30 @@ func testPropSetWithPreposition(object: ObjectWithSplitProperty?) {
253253
// CHECK: #ObjectWithSplitProperty.flagForSomething!setter.1.foreign : (ObjectWithSplitProperty) -> (Bool) -> (), $@convention(objc_method) ({{Bool|ObjCBool}}, ObjectWithSplitProperty) -> ()
254254
object?.flagForSomething = false
255255
}
256+
257+
@propertyWrapper
258+
public struct SomeWrapper {
259+
private var value: Int
260+
261+
262+
public init(wrappedValue: Int) {
263+
value = wrappedValue
264+
}
265+
266+
267+
public var wrappedValue: Int {
268+
get { value }
269+
set { value = newValue }
270+
}
271+
}
272+
273+
class SomeWrapperTests {
274+
@objc @SomeWrapper dynamic var someWrapper: Int = 0
275+
// CHECK-LABEL: sil hidden [ossa] @$s15objc_properties16SomeWrapperTestsC14testAssignmentyyF
276+
// CHECK: [[M:%.*]] = objc_method %0 : $SomeWrapperTests, #SomeWrapperTests.someWrapper!setter.1.foreign
277+
// CHECK: [[C:%.*]] = partial_apply [callee_guaranteed] [[M]]({{.*}}) : $@convention(objc_method)
278+
// CHECK: assign_by_wrapper {{%.*}}: $Int to {{%.*}} : $*SomeWrapper, init {{.*}} : $@callee_guaranteed (Int) -> SomeWrapper, set [[C]] : $@callee_guaranteed (Int) -> ()
279+
func testAssignment() {
280+
someWrapper = 1000
281+
}
282+
}

0 commit comments

Comments
 (0)