Skip to content

Commit

Permalink
Merge pull request swiftlang#23744 from aschwaighofer/silgen_keypath_…
Browse files Browse the repository at this point in the history
…not_external_for_non_public

SILGen: Only set the external decl of a key path component if the accessor is public
  • Loading branch information
aschwaighofer authored Apr 3, 2019
2 parents a533081 + a389f13 commit 0c8920e
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 6 deletions.
15 changes: 9 additions & 6 deletions lib/SILGen/SILGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3217,8 +3217,7 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
bool forPropertyDescriptor) {
/// Returns true if a key path component for the given property or
/// subscript should be externally referenced.
auto shouldUseExternalKeyPathComponent =
[&]() -> bool {
auto shouldUseExternalKeyPathComponent = [&]() -> bool {
return (!forPropertyDescriptor &&
(storage->getModuleContext() != SwiftModule ||
storage->isResilient(SwiftModule, expansion)) &&
Expand All @@ -3227,11 +3226,15 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc,
// Properties that only dispatch via ObjC lookup do not have nor
// need property descriptors, since the selector identifies the
// storage.
// Properties that are not public don't need property descriptors
// either.
(!storage->hasAnyAccessors() ||
!getAccessorDeclRef(getRepresentativeAccessorForKeyPath(storage))
.isForeign));
};

(!getAccessorDeclRef(getRepresentativeAccessorForKeyPath(storage))
.isForeign &&
getAccessorDeclRef(getRepresentativeAccessorForKeyPath(storage))
.getLinkage(ForDefinition) <= SILLinkage::PublicNonABI)));
};

auto strategy = storage->getAccessStrategy(AccessSemantics::Ordinary,
storage->supportsMutation()
? AccessKind::ReadWrite
Expand Down
5 changes: 5 additions & 0 deletions test/IRGen/Inputs/keypaths_c_types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
union c_union {
struct some_struct {
void* data;
} some_field;
};
8 changes: 8 additions & 0 deletions test/IRGen/keypaths_c_types.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// RUN: %target-swift-frontend -primary-file %s -emit-ir -import-objc-header %S/Inputs/keypaths_c_types.h

// This used to crash while trying to emit a reference to the property
// descriptor for the some_field property.

struct Foo {
static let somePath: WritableKeyPath<c_union, some_struct>? = \c_union.some_field
}
6 changes: 6 additions & 0 deletions test/SILGen/Inputs/keypaths_objc.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,9 @@
@property(readonly) NSString *_Nonnull objcProp;

@end

union c_union {
struct some_struct {
void* data;
} some_field;
};
6 changes: 6 additions & 0 deletions test/SILGen/keypaths_objc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,9 @@ func externalObjCProperty() {
// CHECK-NOT: external #NSObject.description
_ = \NSObject.description
}

func sharedCProperty() {
// CHECK: keypath $WritableKeyPath<c_union, some_struct>
// CHECK-NOT: external #c_union.some_field
let dataKeyPath: WritableKeyPath<c_union, some_struct>? = \c_union.some_field
}

0 comments on commit 0c8920e

Please sign in to comment.