Skip to content

Commit dc33b2d

Browse files
committed
[region-isolation] Add support for final actor setters.
rdar://119113959
1 parent 520e124 commit dc33b2d

File tree

2 files changed

+80
-7
lines changed

2 files changed

+80
-7
lines changed

lib/SILOptimizer/Mandatory/TransferNonSendable.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,13 +1033,29 @@ class PartitionOpTranslator {
10331033

10341034
self->stateIndexToEquivalenceClass[iter.first->second.getID()] = value;
10351035

1036-
// Otherwise, we need to compute our flags. Begin by seeing if we have a
1037-
// value that we can prove is not aliased.
1036+
// Otherwise, we need to compute our flags.
1037+
1038+
// First for addresses.
10381039
if (value->getType().isAddress()) {
1039-
if (auto accessStorage = AccessStorage::compute(value))
1040-
if (accessStorage.isUniquelyIdentified() &&
1041-
!isAddressCapturedByPartialApply)
1040+
auto storage = AccessStorageWithBase::compute(value);
1041+
if (storage.storage) {
1042+
// Check if we have a uniquely identified address that was not captured
1043+
// by a partial apply... in such a case, we treat it as no-alias.
1044+
if (storage.storage.isUniquelyIdentified() &&
1045+
!isAddressCapturedByPartialApply) {
10421046
iter.first->getSecond().removeFlag(TrackableValueFlag::isMayAlias);
1047+
}
1048+
1049+
// Then see if the memory base is a ref_element_addr from an address. If
1050+
// so, add the actor derived flag.
1051+
//
1052+
// This is important so we properly handle setters.
1053+
if (isa<RefElementAddrInst>(storage.base)) {
1054+
if (storage.storage.getRoot()->getType().isActor()) {
1055+
iter.first->getSecond().addFlag(TrackableValueFlag::isActorDerived);
1056+
}
1057+
}
1058+
}
10431059
}
10441060

10451061
// Then see if we have a sendable value. By default we assume values are not

test/Concurrency/sendnonsendable_basic.swift

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
////////////////////////
1616

1717
/// Classes are always non-sendable, so this is non-sendable
18-
class NonSendableKlass { // expected-complete-note 25{{}}
18+
class NonSendableKlass { // expected-complete-note 31{{}}
19+
// expected-tns-note @-1 {{}}
1920
var field: NonSendableKlass? = nil
2021

2122
func asyncCall() async {}
@@ -50,11 +51,17 @@ struct SingleFieldKlassBox { // expected-complete-note 2{{consider making struct
5051
var k = NonSendableKlass()
5152
}
5253

53-
struct TwoFieldKlassBox {
54+
struct TwoFieldKlassBox { // expected-note {{}}
5455
var k1 = NonSendableKlass()
5556
var k2 = NonSendableKlass()
5657
}
5758

59+
class TwoFieldKlassClassBox {
60+
var k1 = NonSendableKlass()
61+
var k2 = NonSendableKlass()
62+
var recursive: TwoFieldKlassClassBox? = nil
63+
}
64+
5865
////////////////////////////
5966
// MARK: Actor Self Tests //
6067
////////////////////////////
@@ -1266,3 +1273,53 @@ func controlFlowTest2() async {
12661273

12671274
useValue(x) // expected-tns-note {{access here could race}}
12681275
}
1276+
1277+
////////////////////////
1278+
// MARK: Actor Setter //
1279+
////////////////////////
1280+
1281+
final actor ActorWithSetter {
1282+
var field = NonSendableKlass()
1283+
var twoFieldBox = TwoFieldKlassBox()
1284+
var twoFieldBoxInTuple = (NonSendableKlass(), TwoFieldKlassBox())
1285+
var recursive: ActorWithSetter? = nil
1286+
var classBox = TwoFieldKlassClassBox()
1287+
1288+
func test1() async {
1289+
let x = NonSendableKlass()
1290+
self.field = x
1291+
await transferToMain(x) // expected-tns-warning {{call site passes `self` or a non-sendable argument of this function to another thread, potentially yielding a race with the caller}}
1292+
// expected-complete-warning @-1 {{passing argument of non-sendable type 'NonSendableKlass' into main actor-isolated context may introduce data races}}
1293+
}
1294+
1295+
func test2() async {
1296+
let x = NonSendableKlass()
1297+
self.twoFieldBox.k1 = x
1298+
await transferToMain(x) // expected-tns-warning {{call site passes `self` or a non-sendable argument of this function to another thread, potentially yielding a race with the caller}}
1299+
// expected-complete-warning @-1 {{passing argument of non-sendable type 'NonSendableKlass' into main actor-isolated context may introduce data races}}
1300+
}
1301+
1302+
func test3() async {
1303+
let x = NonSendableKlass()
1304+
self.twoFieldBoxInTuple.1.k1 = x
1305+
await transferToMain(x) // expected-tns-warning {{call site passes `self` or a non-sendable argument of this function to another thread, potentially yielding a race with the caller}}
1306+
// expected-complete-warning @-1 {{passing argument of non-sendable type 'NonSendableKlass' into main actor-isolated context may introduce data races}}
1307+
}
1308+
1309+
func recursive() async {
1310+
let x = NonSendableKlass()
1311+
await self.recursive!.twoFieldBoxInTuple.1.k2 = x
1312+
// expected-warning @-1 {{non-sendable type '(NonSendableKlass, TwoFieldKlassBox)' in implicitly asynchronous access to actor-isolated property 'twoFieldBoxInTuple' cannot cross actor boundary}}
1313+
// expected-warning @-2 {{non-sendable type '(NonSendableKlass, TwoFieldKlassBox)' in implicitly asynchronous access to actor-isolated property 'twoFieldBoxInTuple' cannot cross actor boundary}}
1314+
1315+
await transferToMain(x) // expected-tns-warning {{call site passes `self` or a non-sendable argument of this function to another thread, potentially yielding a race with the caller}}
1316+
// expected-complete-warning @-1 {{passing argument of non-sendable type 'NonSendableKlass' into main actor-isolated context may introduce data races}}
1317+
}
1318+
1319+
func classBox() async {
1320+
let x = NonSendableKlass()
1321+
self.classBox.k1 = x
1322+
await transferToMain(x) // expected-tns-warning {{call site passes `self` or a non-sendable argument of this function to another thread, potentially yielding a race with the caller}}
1323+
// expected-complete-warning @-1 {{passing argument of non-sendable type 'NonSendableKlass' into main actor-isolated context may introduce data races}}
1324+
}
1325+
}

0 commit comments

Comments
 (0)