Skip to content

Commit e85b20f

Browse files
committed
SIL: Stored property initializers in non-resilient modules might need public linkage
Because of a ill-advised core team decision, Swift now allows @_inlineable root initializers on types that are not @_fixed_layout (aa85e45). Since stored property initializers of types that are not @_fixed_layout are permitted to reference non-public symbols, they cannot be serialized and must instead have public linkage. This negates most of the benefit of inlining the constructor in the first place, but oh well. This does not affect resilient builds. Fixes <rdar://problem/38439363>.
1 parent 1e80dda commit e85b20f

File tree

3 files changed

+25
-11
lines changed

3 files changed

+25
-11
lines changed

lib/SIL/SILDeclRef.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -285,19 +285,29 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
285285

286286
// Stored property initializers get the linkage of their containing type.
287287
if (isStoredPropertyInitializer()) {
288-
// If the type is public, the property initializer is referenced from
289-
// inlinable initializers, and has PublicNonABI linkage.
288+
// Three cases:
290289
//
291-
// Note that we don't serialize the presence of an initializer, so there's
292-
// no way to reference one from another module except for this case.
290+
// 1) Type is formally @_fixed_layout. Root initializers can be declared
291+
// @_inlineable. The property initializer must only reference
292+
// public symbols, and is serialized, so we give it PublicNonABI linkage.
293+
//
294+
// 2) Type is not formally @_fixed_layout and the module is not resilient.
295+
// Root initializers can be declared @_inlineable. This is the annoying
296+
// case. We give the initializer public linkage if the type is public.
297+
//
298+
// 3) Type is resilient. The property initializer is never public because
299+
// root initializers cannot be @_inlineable.
300+
//
301+
// FIXME: Get rid of case 2 somehow.
293302
if (isSerialized())
294303
return maybeAddExternal(SILLinkage::PublicNonABI);
295304

296-
// Otherwise, use the visibility of the type itself, because even if the
297-
// property is private, we might reference the initializer from another
298-
// file.
299305
d = cast<NominalTypeDecl>(d->getDeclContext());
300-
neverPublic = true;
306+
307+
// FIXME: This should always be true.
308+
if (d->getDeclContext()->getParentModule()->getResilienceStrategy() ==
309+
ResilienceStrategy::Resilient)
310+
neverPublic = true;
301311
}
302312

303313
// The global addressor is never public for resilient globals.

test/SILGen/extensions_multifile.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/struct_with_initializer.swift -module-name extensions_multifile -enable-sil-ownership | %FileCheck %s
1+
// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/struct_with_initializer.swift -module-name extensions_multifile -enable-sil-ownership | %FileCheck %s --check-prefix=FRAGILE --check-prefix=CHECK
2+
// RUN: %target-swift-frontend -emit-silgen -primary-file %s %S/Inputs/struct_with_initializer.swift -module-name extensions_multifile -enable-sil-ownership -enable-resilience | %FileCheck %s --check-prefix=RESILIENT --check-prefix=CHECK
23

34
// CHECK-LABEL: sil hidden @$S20extensions_multifile12HasInitValueV1zACSi_tcfC : $@convention(method) (Int, @thin HasInitValue.Type) -> @owned HasInitValue {
45
// CHECK: function_ref @$S20extensions_multifile12HasInitValueV1xSivpfi : $@convention(thin) () -> Int
@@ -15,7 +16,9 @@ extension HasPrivateInitValue {
1516
init(z: Int) {}
1617
}
1718

18-
// CHECK-LABEL: sil hidden_external [transparent] @$S20extensions_multifile24PublicStructHasInitValueV1xSivpfi : $@convention(thin) () -> Int
19+
// FRAGILE-LABEL: sil [transparent] @$S20extensions_multifile24PublicStructHasInitValueV1xSivpfi : $@convention(thin) () -> Int
20+
21+
// RESILIENT-LABEL: sil hidden_external [transparent] @$S20extensions_multifile24PublicStructHasInitValueV1xSivpfi : $@convention(thin) () -> Int
1922

2023
extension PublicStructHasInitValue {
2124
init(z: Int) {}

test/SILGen/fixed_layout_attribute.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ public struct NonFixedStruct {
2020
public var storedProperty = global
2121
}
2222

23-
// CHECK-LABEL: sil hidden [transparent] @$S22fixed_layout_attribute14NonFixedStructV14storedPropertySivpfi : $@convention(thin) () -> Int
23+
// FRAGILE-LABEL: sil [transparent] @$S22fixed_layout_attribute14NonFixedStructV14storedPropertySivpfi : $@convention(thin) () -> Int
24+
// RESILIENT-LABEL: sil hidden [transparent] @$S22fixed_layout_attribute14NonFixedStructV14storedPropertySivpfi : $@convention(thin) () -> Int
2425
//
2526
// ... okay to directly reference the addressor here:
2627
// CHECK: function_ref @$S22fixed_layout_attribute6globalSivau

0 commit comments

Comments
 (0)