Skip to content

Commit 2171e15

Browse files
committed
SIL: Private setters need at least hidden visibility for key paths in more cases.
My original fix only addressed the issue for when the property was exactly internal, so we would still run into problems with keypaths and `private(set)` when `-enable-testing` is on, or when referring to `public` properties with private setters from the same module. This generalizes the rule, so that the setter entry point for any property with at least internal visibility also has at least internal visibility, even if the setter is semantically less visible. Fixes rdar://78523318.
1 parent cd35636 commit 2171e15

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

lib/SIL/IR/SILDeclRef.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -367,12 +367,12 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
367367
auto effectiveAccess = d->getEffectiveAccess();
368368

369369
// Private setter implementations for an internal storage declaration should
370-
// be internal as well, so that a dynamically-writable
371-
// keypath can be formed from other files.
370+
// be at least internal as well, so that a dynamically-writable
371+
// keypath can be formed from other files in the same module.
372372
if (auto accessor = dyn_cast<AccessorDecl>(d)) {
373373
if (accessor->isSetter()
374-
&& accessor->getStorage()->getEffectiveAccess() == AccessLevel::Internal)
375-
effectiveAccess = AccessLevel::Internal;
374+
&& accessor->getStorage()->getEffectiveAccess() >= AccessLevel::Internal)
375+
effectiveAccess = std::max(effectiveAccess, AccessLevel::Internal);
376376
}
377377

378378
switch (effectiveAccess) {

test/SILGen/accessors_testing.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %target-swift-emit-silgen -parse-as-library -module-name accessors %s | %FileCheck %s
2+
// RUN: %target-swift-emit-silgen -parse-as-library -enable-testing -module-name accessors %s | %FileCheck %s
3+
4+
// rdar://78523318: Ensure that private(set) accessors for internal or more
5+
// visible properties have hidden linkage, because other code inside the module
6+
// needs to reference the setter to form a key path.
7+
8+
public struct Foo {
9+
// CHECK-LABEL: sil hidden [ossa] @$s9accessors3FooV6internSivs
10+
private(set) internal var intern: Int {
11+
get { return 0 }
12+
set {}
13+
}
14+
// CHECK-LABEL: sil hidden [ossa] @$s9accessors3FooV3pubSivs
15+
private(set) public var pub: Int {
16+
get { return 0 }
17+
set {}
18+
}
19+
20+
public mutating func exercise() {
21+
_ = intern
22+
_ = pub
23+
intern = 0
24+
pub = 0
25+
}
26+
}
27+

0 commit comments

Comments
 (0)