Skip to content

Commit 56888e2

Browse files
dingobyejrose-apple
authored andcommitted
[IRGen] Do not emit ObjC property ivar field for non-trivially-representable types. (#21976)
This patch prevents writing ivar field for ObjC property whose type is not trivially representable in ObjC within its DeclContext. For example, in the case of the property `@objc var foo: String`, it is accessed as an NSString on the ObjC side. Without this patch, this property is backed with an ivar, to which direct accesses would fail. Resolves: SR-9557.
1 parent 26457bf commit 56888e2

File tree

3 files changed

+14
-10
lines changed

3 files changed

+14
-10
lines changed

lib/IRGen/GenClass.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,6 +1867,7 @@ namespace {
18671867
llvm::raw_svector_ostream outs(out);
18681868

18691869
auto propTy = prop->getValueInterfaceType();
1870+
auto propDC = prop->getDeclContext();
18701871

18711872
// Emit the type encoding for the property.
18721873
outs << 'T';
@@ -1884,13 +1885,13 @@ namespace {
18841885
if (prop->getAttrs().hasAttribute<NSManagedAttr>())
18851886
outs << ",D";
18861887

1887-
auto isObject = prop->getDeclContext()->mapTypeIntoContext(propTy)
1888+
auto isObject = propDC->mapTypeIntoContext(propTy)
18881889
->hasRetainablePointerRepresentation();
18891890
auto hasObjectEncoding = typeEnc[0] == '@';
18901891

18911892
// Determine the assignment semantics.
18921893
// Get-only properties are (readonly).
1893-
if (!prop->isSettable(prop->getDeclContext()))
1894+
if (!prop->isSettable(propDC))
18941895
outs << ",R";
18951896
// Weak and Unowned properties are (weak).
18961897
else if (prop->getAttrs().hasAttribute<ReferenceOwnershipAttr>())
@@ -1908,9 +1909,12 @@ namespace {
19081909
else
19091910
(void)0;
19101911

1911-
// If the property is an instance property and has storage, emit the ivar
1912-
// name last.
1913-
if (!prop->isStatic() && prop->hasStorage())
1912+
// If the property is an instance property and has storage, and meanwhile
1913+
// its type is trivially representable in ObjC, emit the ivar name last.
1914+
bool isTriviallyRepresentable =
1915+
propTy->isTriviallyRepresentableIn(ForeignLanguage::ObjectiveC,
1916+
propDC);
1917+
if (!prop->isStatic() && prop->hasStorage() && isTriviallyRepresentable)
19141918
outs << ",V" << prop->getName();
19151919
}
19161920

test/IRGen/objc_bridge.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ import Foundation
100100

101101
// CHECK: @_PROPERTIES__TtC11objc_bridge3Bas = private constant { i32, i32, [5 x { i8*, i8* }] } {
102102

103-
// CHECK: [[OBJC_BLOCK_PROPERTY:@.*]] = private unnamed_addr constant [11 x i8] c"T@?,N,C,Vx\00"
103+
// CHECK: [[OBJC_BLOCK_PROPERTY:@.*]] = private unnamed_addr constant [8 x i8] c"T@?,N,C\00"
104104
// CHECK: @_PROPERTIES__TtC11objc_bridge21OptionalBlockProperty = private constant {{.*}} [[OBJC_BLOCK_PROPERTY]]
105105

106106
func getDescription(_ o: NSObject) -> String {

test/IRGen/objc_property_attrs.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ class Foo: NSManagedObject {
5050

5151
// -- Bridged value types
5252

53-
// nonatomic, copy, ivar k
54-
// CHECK: private unnamed_addr constant {{.*}} c"T@\22NSString\22,N,C,Vk\00"
53+
// nonatomic, copy
54+
// CHECK: private unnamed_addr constant {{.*}} c"T@\22NSString\22,N,C\00"
5555
@objc var k: String = ""
56-
// nonatomic, readonly, ivar l
57-
// CHECK: private unnamed_addr constant {{.*}} c"T@\22NSString\22,N,R,Vl\00"
56+
// nonatomic, readonly
57+
// CHECK: private unnamed_addr constant {{.*}} c"T@\22NSString\22,N,R\00"
5858
@objc let l: String? = nil
5959

6060
// -- Protocol types:

0 commit comments

Comments
 (0)