Skip to content

Commit 94de12b

Browse files
authored
Merge pull request swiftlang#41788 from tshortli/back-deploy-accessors
SILGen: Fix accessor functions with `@_backDeploy`
2 parents 58b414d + c1e326c commit 94de12b

File tree

8 files changed

+127
-9
lines changed

8 files changed

+127
-9
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6315,7 +6315,8 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
63156315
/// diagnosed errors during type checking.
63166316
FuncDecl *getDistributedThunk() const;
63176317

6318-
/// Returns 'true' if the function has the @c @_backDeploy attribute.
6318+
/// Returns 'true' if the function has (or inherits) the @c @_backDeploy
6319+
/// attribute.
63196320
bool isBackDeployed() const;
63206321

63216322
PolymorphicEffectKind getPolymorphicEffectKind(EffectKind kind) const;

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6320,5 +6320,9 @@ ERROR(attr_incompatible_with_back_deploy,none,
63206320
"'%0' cannot be applied to a back deployed %1",
63216321
(DeclAttribute, DescriptiveDeclKind))
63226322

6323+
ERROR(back_deploy_not_on_coroutine,none,
6324+
"'%0' is not supported on coroutine %1",
6325+
(DeclAttribute, DescriptiveDeclKind))
6326+
63236327
#define UNDEFINE_DIAGNOSTIC_MACROS
63246328
#include "DefineDiagnosticMacros.h"

lib/AST/Decl.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,12 @@ Decl::getBackDeployBeforeOSVersion(PlatformKind Kind) const {
386386
}
387387
}
388388
}
389+
390+
// Accessors may inherit `@_backDeploy`.
391+
if (getKind() == DeclKind::Accessor) {
392+
return cast<AccessorDecl>(this)->getStorage()->getBackDeployBeforeOSVersion(Kind);
393+
}
394+
389395
return None;
390396
}
391397

@@ -7649,7 +7655,16 @@ bool AbstractFunctionDecl::isSendable() const {
76497655
}
76507656

76517657
bool AbstractFunctionDecl::isBackDeployed() const {
7652-
return getAttrs().hasAttribute<BackDeployAttr>();
7658+
if (getAttrs().hasAttribute<BackDeployAttr>())
7659+
return true;
7660+
7661+
// Property and subscript accessors inherit the attribute.
7662+
if (auto *AD = dyn_cast<AccessorDecl>(this)) {
7663+
if (AD->getStorage()->getAttrs().hasAttribute<BackDeployAttr>())
7664+
return true;
7665+
}
7666+
7667+
return false;
76537668
}
76547669

76557670
BraceStmt *AbstractFunctionDecl::getBody(bool canSynthesize) const {

lib/SILGen/SILGenApply.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,6 +1312,7 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
13121312

13131313
} else if (auto *declRef = dyn_cast<DeclRefExpr>(fn)) {
13141314
assert(isa<FuncDecl>(declRef->getDecl()) && "non-function super call?!");
1315+
// FIXME(backDeploy): Handle calls to back deployed methods on super?
13151316
constant = SILDeclRef(declRef->getDecl())
13161317
.asForeign(requiresForeignEntryPoint(declRef->getDecl()));
13171318

@@ -5767,8 +5768,11 @@ SILGenFunction::prepareSubscriptIndices(SubscriptDecl *subscript,
57675768
}
57685769

57695770
SILDeclRef SILGenModule::getAccessorDeclRef(AccessorDecl *accessor) {
5770-
return SILDeclRef(accessor, SILDeclRef::Kind::Func)
5771-
.asForeign(requiresForeignEntryPoint(accessor));
5771+
auto declRef = SILDeclRef(accessor, SILDeclRef::Kind::Func);
5772+
if (accessor->isBackDeployed())
5773+
return declRef.asBackDeploymentKind(SILDeclRef::BackDeploymentKind::Thunk);
5774+
5775+
return declRef.asForeign(requiresForeignEntryPoint(accessor));
57725776
}
57735777

57745778
/// Emit a call to a getter.

lib/Sema/TypeCheckAttr.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3533,6 +3533,21 @@ void AttributeChecker::checkBackDeployAttrs(ArrayRef<BackDeployAttr *> Attrs) {
35333533
}
35343534
}
35353535

3536+
// FIXME(backDeploy): support coroutines rdar://90111169
3537+
auto diagnoseCoroutineIfNecessary = [&](AccessorDecl *AD) {
3538+
if (AD->isCoroutine())
3539+
diagnose(Attr->getLocation(), diag::back_deploy_not_on_coroutine,
3540+
Attr, AD->getDescriptiveKind());
3541+
};
3542+
if (auto *ASD = dyn_cast<AbstractStorageDecl>(D)) {
3543+
ASD->visitEmittedAccessors([&](AccessorDecl *AD) {
3544+
diagnoseCoroutineIfNecessary(AD);
3545+
});
3546+
}
3547+
if (auto *AD = dyn_cast<AccessorDecl>(D)) {
3548+
diagnoseCoroutineIfNecessary(AD);
3549+
}
3550+
35363551
auto AtLoc = Attr->AtLoc;
35373552
auto Platform = Attr->Platform;
35383553

test/ModuleInterface/back-deploy-attr.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,27 +45,23 @@ public struct TopLevelStruct {
4545
// CHECK: @_backDeploy(macOS 12.0)
4646
// FROMSOURCE: public var backDeployedPropertyWithAccessors: Swift.Int {
4747
// FROMSOURCE: get { 45 }
48-
// FROMSOURCE: set(newValue) { print("set property") }
4948
// FROMSOURCE: }
5049
// FROMMODULE: public var backDeployedPropertyWithAccessors: Swift.Int
5150
@available(macOS 11.0, *)
5251
@_backDeploy(macOS 12.0)
5352
public var backDeployedPropertyWithAccessors: Int {
5453
get { 45 }
55-
set(newValue) { print("set property") }
5654
}
5755

5856
// CHECK: @_backDeploy(macOS 12.0)
5957
// FROMSOURCE: public subscript(index: Swift.Int) -> Swift.Int {
6058
// FROMSOURCE: get { 46 }
61-
// FROMSOURCE: set(newValue) { print("set subscript") }
6259
// FROMSOURCE: }
6360
// FROMMODULE: public subscript(index: Swift.Int) -> Swift.Int
6461
@available(macOS 11.0, *)
6562
@_backDeploy(macOS 12.0)
6663
public subscript(index: Int) -> Int {
6764
get { 46 }
68-
set(newValue) { print("set subscript") }
6965
}
7066
}
7167

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// RUN: %target-swift-emit-sil -parse-as-library -module-name back_deploy %s -target %target-cpu-apple-macosx10.50 -verify
2+
// RUN: %target-swift-emit-silgen -parse-as-library -module-name back_deploy %s | %FileCheck %s
3+
// RUN: %target-swift-emit-silgen -parse-as-library -module-name back_deploy %s -target %target-cpu-apple-macosx10.50 | %FileCheck %s
4+
// RUN: %target-swift-emit-silgen -parse-as-library -module-name back_deploy %s -target %target-cpu-apple-macosx10.60 | %FileCheck %s
5+
6+
// REQUIRES: OS=macosx
7+
8+
@available(macOS 10.50, *)
9+
public struct TopLevelStruct {
10+
// -- Fallback definition for TopLevelStruct.property.getter
11+
// CHECK-LABEL: sil non_abi [serialized] [available 10.51] [ossa] @$s11back_deploy14TopLevelStructV8propertyACvgTwB : $@convention(method) (TopLevelStruct) -> TopLevelStruct
12+
// CHECK: bb0([[SELF:%.*]] : $TopLevelStruct):
13+
// CHECK: return [[SELF]] : $TopLevelStruct
14+
15+
// -- Back deployment thunk for TopLevelStruct.property.getter
16+
// CHECK-LABEL: sil non_abi [serialized] [thunk] [available 10.51] [ossa] @$s11back_deploy14TopLevelStructV8propertyACvgTwb : $@convention(method) (TopLevelStruct) -> TopLevelStruct
17+
// CHECK: bb0([[BB0_ARG:%.*]] : $TopLevelStruct):
18+
// CHECK: [[MAJOR:%.*]] = integer_literal $Builtin.Word, 10
19+
// CHECK: [[MINOR:%.*]] = integer_literal $Builtin.Word, 52
20+
// CHECK: [[PATCH:%.*]] = integer_literal $Builtin.Word, 0
21+
// CHECK: [[OSVFN:%.*]] = function_ref @$ss26_stdlib_isOSVersionAtLeastyBi1_Bw_BwBwtF : $@convention(thin) (Builtin.Word, Builtin.Word, Builtin.Word) -> Builtin.Int1
22+
// CHECK: [[AVAIL:%.*]] = apply [[OSVFN]]([[MAJOR]], [[MINOR]], [[PATCH]]) : $@convention(thin) (Builtin.Word, Builtin.Word, Builtin.Word) -> Builtin.Int1
23+
// CHECK: cond_br [[AVAIL]], [[AVAIL_BB:bb[0-9]+]], [[UNAVAIL_BB:bb[0-9]+]]
24+
//
25+
// CHECK: [[UNAVAIL_BB]]:
26+
// CHECK: [[FALLBACKFN:%.*]] = function_ref @$s11back_deploy14TopLevelStructV8propertyACvgTwB : $@convention(method) (TopLevelStruct) -> TopLevelStruct
27+
// CHECK: [[FALLBACKRES:%.*]] = apply [[FALLBACKFN]]([[BB0_ARG]]) : $@convention(method) (TopLevelStruct) -> TopLevelStruct
28+
// CHECK: br [[RETURN_BB:bb[0-9]+]]([[FALLBACKRES]] : $TopLevelStruct)
29+
//
30+
// CHECK: [[AVAIL_BB]]:
31+
// CHECK: [[ORIGFN:%.*]] = function_ref @$s11back_deploy14TopLevelStructV8propertyACvg : $@convention(method) (TopLevelStruct) -> TopLevelStruct
32+
// CHECK: [[ORIGRES:%.*]] = apply [[ORIGFN]]([[BB0_ARG]]) : $@convention(method) (TopLevelStruct) -> TopLevelStruct
33+
// CHECK: br [[RETURN_BB]]([[ORIGRES]] : $TopLevelStruct)
34+
//
35+
// CHECK: [[RETURN_BB]]([[RETURN_BB_ARG:%.*]] : $TopLevelStruct)
36+
// CHECK: return [[RETURN_BB_ARG]] : $TopLevelStruct
37+
38+
// -- Original definition of TopLevelStruct.property.getter
39+
// CHECK-LABEL: sil [serialized] [available 10.51] [ossa] @$s11back_deploy14TopLevelStructV8propertyACvg : $@convention(method) (TopLevelStruct) -> TopLevelStruct
40+
@available(macOS 10.51, *)
41+
@_backDeploy(macOS 10.52)
42+
public var property: TopLevelStruct { self }
43+
}
44+
45+
// CHECK-LABEL: sil hidden [available 10.51] [ossa] @$s11back_deploy6calleryyAA14TopLevelStructVF : $@convention(thin) (TopLevelStruct) -> ()
46+
// CHECK: bb0([[STRUCT_ARG:%.*]] : $TopLevelStruct):
47+
@available(macOS 10.51, *)
48+
func caller(_ s: TopLevelStruct) {
49+
// -- Verify the thunk is called
50+
// CHECK: {{%.*}} = function_ref @$s11back_deploy14TopLevelStructV8propertyACvgTwb : $@convention(method) (TopLevelStruct) -> TopLevelStruct
51+
_ = s.property
52+
}

test/attr/attr_backDeploy.swift

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public func backDeployedTopLevelFunc() {}
1414
@usableFromInline
1515
internal func backDeployedUsableFromInlineTopLevelFunc() {}
1616

17-
// OK: function decls in a struct
17+
// OK: function/property/subscript decls in a struct
1818
public struct TopLevelStruct {
1919
@available(macOS 11.0, *)
2020
@_backDeploy(macOS 12.0)
@@ -23,6 +23,10 @@ public struct TopLevelStruct {
2323
@available(macOS 11.0, *)
2424
@_backDeploy(macOS 12.0)
2525
public var backDeployedComputedProperty: Int { 98 }
26+
27+
@available(macOS 11.0, *)
28+
@_backDeploy(macOS 12.0)
29+
public subscript(_ index: Int) -> Int { index }
2630
}
2731

2832
// OK: final function decls in a non-final class
@@ -128,6 +132,33 @@ protocol CannotBackDeployProtocol {}
128132
@_backDeploy(macOS 12.0) // expected-error {{'@_backDeploy' attribute cannot be applied to this declaration}}
129133
public actor CannotBackDeployActor {}
130134

135+
// FIXME(backDeploy): support coroutines rdar://90111169
136+
public struct CannotBackDeployCoroutines {
137+
@available(macOS 11.0, *)
138+
@_backDeploy(macOS 12.0) // expected-error {{'@_backDeploy' is not supported on coroutine _modify accessor}}
139+
public var readWriteProperty: Int {
140+
get { 42 }
141+
set(newValue) {}
142+
}
143+
144+
@available(macOS 11.0, *)
145+
@_backDeploy(macOS 12.0) // expected-error {{'@_backDeploy' is not supported on coroutine _modify accessor}}
146+
public subscript(at index: Int) -> Int {
147+
get { 42 }
148+
set(newValue) {}
149+
}
150+
151+
public var explicitReadAndModify: Int {
152+
@available(macOS 11.0, *)
153+
@_backDeploy(macOS 12.0) // expected-error {{'@_backDeploy' is not supported on coroutine _read accessor}}
154+
_read { yield 42 }
155+
156+
@available(macOS 11.0, *)
157+
@_backDeploy(macOS 12.0) // expected-error {{'@_backDeploy' is not supported on coroutine _modify accessor}}
158+
_modify {}
159+
}
160+
}
161+
131162
// MARK: - Incompatible declarations
132163

133164
@_backDeploy(macOS 12.0) // expected-error {{'@_backDeploy' may not be used on fileprivate declarations}}

0 commit comments

Comments
 (0)