Skip to content

Commit b246edd

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 9f8cc21 commit b246edd

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
@@ -399,12 +399,12 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
399399
auto effectiveAccess = d->getEffectiveAccess();
400400

401401
// Private setter implementations for an internal storage declaration should
402-
// be internal as well, so that a dynamically-writable
403-
// keypath can be formed from other files.
402+
// be at least internal as well, so that a dynamically-writable
403+
// keypath can be formed from other files in the same module.
404404
if (auto accessor = dyn_cast<AccessorDecl>(d)) {
405405
if (accessor->isSetter()
406-
&& accessor->getStorage()->getEffectiveAccess() == AccessLevel::Internal)
407-
effectiveAccess = AccessLevel::Internal;
406+
&& accessor->getStorage()->getEffectiveAccess() >= AccessLevel::Internal)
407+
effectiveAccess = std::max(effectiveAccess, AccessLevel::Internal);
408408
}
409409

410410
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)