diff --git a/lib/SIL/SILDeclRef.cpp b/lib/SIL/SILDeclRef.cpp index b5d81b149fb67..8cbfb9fae9800 100644 --- a/lib/SIL/SILDeclRef.cpp +++ b/lib/SIL/SILDeclRef.cpp @@ -430,6 +430,33 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const { if (isClangImported()) return SILLinkage::Shared; + // Stored property initializers get the linkage of their containing type. + if (isStoredPropertyInitializer()) { + // If the property is public, the initializer needs to be public, because + // it might be referenced from an inlineable initializer. + // + // Note that we don't serialize the presence of an initializer, so there's + // no way to reference one from another module except for this case. + // + // This is silly, and we need a proper resilience story here. + if (d->getEffectiveAccess() == Accessibility::Public) + return maybeAddExternal(SILLinkage::Public); + + d = cast(d->getDeclContext()); + + // Otherwise, use the visibility of the type itself, because even if the + // property is private, we might reference the initializer from another + // file. + switch (d->getEffectiveAccess()) { + case Accessibility::Private: + case Accessibility::FilePrivate: + return maybeAddExternal(SILLinkage::Private); + + default: + return maybeAddExternal(SILLinkage::Hidden); + } + } + // Otherwise, we have external linkage. switch (d->getEffectiveAccess()) { case Accessibility::Private: diff --git a/test/SILGen/Inputs/struct_with_initializer.swift b/test/SILGen/Inputs/struct_with_initializer.swift index 0c3625d52bd05..854fd57035199 100644 --- a/test/SILGen/Inputs/struct_with_initializer.swift +++ b/test/SILGen/Inputs/struct_with_initializer.swift @@ -2,3 +2,11 @@ struct HasInitValue { var x = 10 var y: String = "" } + +struct HasPrivateInitValue { + private var x = 10 +} + +public struct PublicStructHasInitValue { + var x = 10 +} diff --git a/test/SILGen/extensions_multifile.swift b/test/SILGen/extensions_multifile.swift index 842caed7825f0..41c7c4b9d970e 100644 --- a/test/SILGen/extensions_multifile.swift +++ b/test/SILGen/extensions_multifile.swift @@ -8,3 +8,15 @@ extension HasInitValue { init(z: Int) {} } + +// CHECK-LABEL: sil hidden_external [transparent] @_T020extensions_multifile19HasPrivateInitValueV1x33_0A683B047698EED319CF48214D7F519DLLSivfi : $@convention(thin) () -> Int + +extension HasPrivateInitValue { + init(z: Int) {} +} + +// CHECK-LABEL: sil hidden_external [transparent] @_T020extensions_multifile24PublicStructHasInitValueV1xSivfi : $@convention(thin) () -> Int + +extension PublicStructHasInitValue { + init(z: Int) {} +}