Skip to content

Commit a389f13

Browse files
committed
SILGen: Only set the external decl of a key path component if the accessor is public
rdar://49064011
1 parent 52e8340 commit a389f13

File tree

5 files changed

+34
-6
lines changed

5 files changed

+34
-6
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3217,8 +3217,7 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
32173217
bool forPropertyDescriptor) {
32183218
/// Returns true if a key path component for the given property or
32193219
/// subscript should be externally referenced.
3220-
auto shouldUseExternalKeyPathComponent =
3221-
[&]() -> bool {
3220+
auto shouldUseExternalKeyPathComponent = [&]() -> bool {
32223221
return (!forPropertyDescriptor &&
32233222
(storage->getModuleContext() != SwiftModule ||
32243223
storage->isResilient(SwiftModule, expansion)) &&
@@ -3227,11 +3226,15 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
32273226
// Properties that only dispatch via ObjC lookup do not have nor
32283227
// need property descriptors, since the selector identifies the
32293228
// storage.
3229+
// Properties that are not public don't need property descriptors
3230+
// either.
32303231
(!storage->hasAnyAccessors() ||
3231-
!getAccessorDeclRef(getRepresentativeAccessorForKeyPath(storage))
3232-
.isForeign));
3233-
};
3234-
3232+
(!getAccessorDeclRef(getRepresentativeAccessorForKeyPath(storage))
3233+
.isForeign &&
3234+
getAccessorDeclRef(getRepresentativeAccessorForKeyPath(storage))
3235+
.getLinkage(ForDefinition) <= SILLinkage::PublicNonABI)));
3236+
};
3237+
32353238
auto strategy = storage->getAccessStrategy(AccessSemantics::Ordinary,
32363239
storage->supportsMutation()
32373240
? AccessKind::ReadWrite

test/IRGen/Inputs/keypaths_c_types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
union c_union {
2+
struct some_struct {
3+
void* data;
4+
} some_field;
5+
};

test/IRGen/keypaths_c_types.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %target-swift-frontend -primary-file %s -emit-ir -import-objc-header %S/Inputs/keypaths_c_types.h
2+
3+
// This used to crash while trying to emit a reference to the property
4+
// descriptor for the some_field property.
5+
6+
struct Foo {
7+
static let somePath: WritableKeyPath<c_union, some_struct>? = \c_union.some_field
8+
}

test/SILGen/Inputs/keypaths_objc.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,9 @@
55
@property(readonly) NSString *_Nonnull objcProp;
66

77
@end
8+
9+
union c_union {
10+
struct some_struct {
11+
void* data;
12+
} some_field;
13+
};

test/SILGen/keypaths_objc.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,9 @@ func externalObjCProperty() {
9696
// CHECK-NOT: external #NSObject.description
9797
_ = \NSObject.description
9898
}
99+
100+
func sharedCProperty() {
101+
// CHECK: keypath $WritableKeyPath<c_union, some_struct>
102+
// CHECK-NOT: external #c_union.some_field
103+
let dataKeyPath: WritableKeyPath<c_union, some_struct>? = \c_union.some_field
104+
}

0 commit comments

Comments
 (0)