From a389f13ee9b81864f0971add42c44cddc5e3e555 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Tue, 2 Apr 2019 10:07:10 -0700 Subject: [PATCH] SILGen: Only set the external decl of a key path component if the accessor is public rdar://49064011 --- lib/SILGen/SILGenExpr.cpp | 15 +++++++++------ test/IRGen/Inputs/keypaths_c_types.h | 5 +++++ test/IRGen/keypaths_c_types.swift | 8 ++++++++ test/SILGen/Inputs/keypaths_objc.h | 6 ++++++ test/SILGen/keypaths_objc.swift | 6 ++++++ 5 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 test/IRGen/Inputs/keypaths_c_types.h create mode 100644 test/IRGen/keypaths_c_types.swift diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index 06e5a47880935..7dd7aab4fed19 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -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)) && @@ -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 diff --git a/test/IRGen/Inputs/keypaths_c_types.h b/test/IRGen/Inputs/keypaths_c_types.h new file mode 100644 index 0000000000000..c473bcec9c2f9 --- /dev/null +++ b/test/IRGen/Inputs/keypaths_c_types.h @@ -0,0 +1,5 @@ +union c_union { + struct some_struct { + void* data; + } some_field; +}; diff --git a/test/IRGen/keypaths_c_types.swift b/test/IRGen/keypaths_c_types.swift new file mode 100644 index 0000000000000..fb384249b5ad2 --- /dev/null +++ b/test/IRGen/keypaths_c_types.swift @@ -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_field +} diff --git a/test/SILGen/Inputs/keypaths_objc.h b/test/SILGen/Inputs/keypaths_objc.h index 8ee4904a55682..326fb269fe106 100644 --- a/test/SILGen/Inputs/keypaths_objc.h +++ b/test/SILGen/Inputs/keypaths_objc.h @@ -5,3 +5,9 @@ @property(readonly) NSString *_Nonnull objcProp; @end + +union c_union { + struct some_struct { + void* data; + } some_field; +}; diff --git a/test/SILGen/keypaths_objc.swift b/test/SILGen/keypaths_objc.swift index 0dbf0816d12f1..e5a1f14468188 100644 --- a/test/SILGen/keypaths_objc.swift +++ b/test/SILGen/keypaths_objc.swift @@ -96,3 +96,9 @@ func externalObjCProperty() { // CHECK-NOT: external #NSObject.description _ = \NSObject.description } + +func sharedCProperty() { + // CHECK: keypath $WritableKeyPath + // CHECK-NOT: external #c_union.some_field + let dataKeyPath: WritableKeyPath? = \c_union.some_field +}