Skip to content

Commit cf2a338

Browse files
authored
Merge pull request #71028 from gottesmm/pr-524e0ec6510c6afb2182d3f5538e7c333a323871
[region-isolation] Fix support for GlobalActor guarded variables and wordsmith some diagnostics.
2 parents 1dec00a + 3641050 commit cf2a338

12 files changed

+315
-223
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -893,16 +893,16 @@ NOTE(sil_referencebinding_inout_binding_here, none,
893893
WARNING(regionbasedisolation_selforargtransferred, none,
894894
"call site passes `self` or a non-sendable argument of this function to another thread, potentially yielding a race with the caller", ())
895895
WARNING(regionbasedisolation_transfer_yields_race_no_isolation, none,
896-
"transferred value of non-Sendable type %0 that could race with later accesses",
896+
"transferring value of non-Sendable type %0; later accesses could race",
897897
(Type))
898898
WARNING(regionbasedisolation_transfer_yields_race_with_isolation, none,
899-
"passing argument of non-sendable type %0 from %1 context to %2 context at this call site could yield a race with accesses later in this function",
899+
"transferring value of non-Sendable type %0 from %1 context to %2 context; later accesses could race",
900900
(Type, ActorIsolation, ActorIsolation))
901901
WARNING(regionbasedisolation_transfer_yields_race_transferring_parameter, none,
902-
"transferred value of non-Sendable type %0 into transferring parameter; later accesses could result in races",
902+
"transferring value of non-Sendable type %0 into transferring parameter; later accesses could race",
903903
(Type))
904904
WARNING(regionbasedisolation_transfer_yields_race_stronglytransferred_binding, none,
905-
"binding of non-Sendable type %0 accessed after being transferred; later accesses could result in races",
905+
"binding of non-Sendable type %0 accessed after being transferred; later accesses could race",
906906
(Type))
907907
NOTE(regionbasedisolation_maybe_race, none,
908908
"access here could race", ())

lib/SILOptimizer/Analysis/RegionAnalysis.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2924,6 +2924,17 @@ TrackableValue RegionAnalysisValueMap::getTrackableValue(
29242924
iter.first->getSecond().addFlag(TrackableValueFlag::isActorDerived);
29252925
}
29262926
}
2927+
2928+
// See if the memory base is a global_addr from a global actor protected global.
2929+
if (auto *ga = dyn_cast<GlobalAddrInst>(storage.base)) {
2930+
if (auto *global = ga->getReferencedGlobal()) {
2931+
if (auto *globalDecl = global->getDecl()) {
2932+
if (getActorIsolation(globalDecl).isGlobalActor()) {
2933+
iter.first->getSecond().addFlag(TrackableValueFlag::isActorDerived);
2934+
}
2935+
}
2936+
}
2937+
}
29272938
}
29282939
}
29292940

test/Concurrency/experimental_feature_strictconcurrency.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ func iterate(stream: AsyncStream<Int>) async {
3131
// FIXME: Region isolation should consider a value from a 'nonisolated(unsafe)'
3232
// declaration to be in a disconnected region
3333

34-
// expected-region-isolation-warning@+2 {{passing argument of non-sendable type 'AsyncStream<Int>.Iterator' from main actor-isolated context to nonisolated context at this call site could yield a race with accesses later in this function}}
34+
// expected-region-isolation-warning@+2 {{transferring value of non-Sendable type 'AsyncStream<Int>.Iterator' from main actor-isolated context to nonisolated context; later accesses could race}}
3535
// expected-region-isolation-note@+1 {{access here could race}}
3636
while let element = await it.next() {
3737
print(element)
3838
}
3939

40-
// expected-region-isolation-warning@+2 {{passing argument of non-sendable type 'AsyncStream<Int>.Iterator' from main actor-isolated context to nonisolated context at this call site could yield a race with accesses later in this function}}
40+
// expected-region-isolation-warning@+2 {{transferring value of non-Sendable type 'AsyncStream<Int>.Iterator' from main actor-isolated context to nonisolated context; later accesses could race}}
4141
// expected-region-isolation-note@+1 {{access here could race}}
4242
for await x in stream {
4343
print(x)

test/Concurrency/sendable_checking.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ func testNonSendableBaseArg() async {
273273
let t = NonSendable()
274274
await t.update()
275275
// expected-targeted-and-complete-warning @-1 {{passing argument of non-sendable type 'NonSendable' into main actor-isolated context may introduce data races}}
276-
// expected-tns-warning@-2 {{passing argument of non-sendable type 'NonSendable' from nonisolated context to main actor-isolated context at this call site could yield a race with accesses later in this function}}
276+
// expected-tns-warning@-2 {{transferring value of non-Sendable type 'NonSendable' from nonisolated context to main actor-isolated context; later accesses could race}}
277277

278278
_ = await t.x
279279
// expected-warning @-1 {{non-sendable type 'NonSendable' passed in implicitly asynchronous call to main actor-isolated property 'x' cannot cross actor boundary}}

test/Concurrency/transfernonsendable.swift

Lines changed: 61 additions & 61 deletions
Large diffs are not rendered by default.

test/Concurrency/transfernonsendable_asynclet.swift

Lines changed: 54 additions & 54 deletions
Large diffs are not rendered by default.

test/Concurrency/transfernonsendable_cfg.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ bb2:
4444
bb3:
4545
%transferKlass = function_ref @transferKlass : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
4646
apply [caller_isolation=nonisolated] [callee_isolation=global_actor] %transferKlass(%klass) : $@convention(thin) @async (@guaranteed NonSendableKlass) -> ()
47-
// expected-warning @-1 {{passing argument of non-sendable type 'NonSendableKlass' from nonisolated context to global actor '<null>'-isolated context at this call site could yield a race with accesses later in this function}}
47+
// expected-warning @-1 {{transferring value of non-Sendable type 'NonSendableKlass' from nonisolated context to global actor '<null>'-isolated context; later accesses could race}}
4848
%useKlass = function_ref @useKlass : $@convention(thin) (@guaranteed NonSendableKlass) -> ()
4949
apply %useKlass(%klass) : $@convention(thin) (@guaranteed NonSendableKlass) -> ()
5050
// expected-note @-1 {{access here could race}}

test/Concurrency/transfernonsendable_global_actor.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ private class NonSendableLinkedListNode<T> { // expected-complete-note 3{{}}
8989
@GlobalActor func useGlobalActor5() async {
9090
let x = NonSendableLinkedListNode<Int>()
9191

92-
await transferToNonIsolated(x) // expected-tns-warning {{passing argument of non-sendable type 'NonSendableLinkedListNode<Int>' from global actor 'GlobalActor'-isolated context to nonisolated context at this call site could yield a race with accesses later in this function}}
92+
await transferToNonIsolated(x) // expected-tns-warning {{transferring value of non-Sendable type 'NonSendableLinkedListNode<Int>' from global actor 'GlobalActor'-isolated context to nonisolated context; later accesses could race}}
9393
// expected-complete-warning @-1 {{passing argument of non-sendable type 'NonSendableLinkedListNode<Int>' outside of global actor 'GlobalActor'-isolated context may introduce data races}}
9494

9595
useValue(x) // expected-tns-note {{access here could race}}
@@ -104,7 +104,7 @@ private struct StructContainingValue { // expected-complete-note 2{{}}
104104
var x = StructContainingValue()
105105
x = StructContainingValue()
106106

107-
await transferToNonIsolated(x) // expected-tns-warning {{passing argument of non-sendable type 'StructContainingValue' from global actor 'GlobalActor'-isolated context to nonisolated context at this call site could yield a race with accesses later in this function}}
107+
await transferToNonIsolated(x) // expected-tns-warning {{transferring value of non-Sendable type 'StructContainingValue' from global actor 'GlobalActor'-isolated context to nonisolated context; later accesses could race}}
108108
// expected-complete-warning @-1 {{passing argument of non-sendable type 'StructContainingValue' outside of global actor 'GlobalActor'-isolated context may introduce data races}}
109109

110110
useValue(x) // expected-tns-note {{access here could race}}
@@ -124,7 +124,7 @@ private struct StructContainingValue { // expected-complete-note 2{{}}
124124
var x = (NonSendableLinkedList<Int>(), NonSendableLinkedList<Int>())
125125
x = (NonSendableLinkedList<Int>(), NonSendableLinkedList<Int>())
126126

127-
await transferToNonIsolated(x) // expected-tns-warning {{passing argument of non-sendable type '(NonSendableLinkedList<Int>, NonSendableLinkedList<Int>)' from global actor 'GlobalActor'-isolated context to nonisolated context at this call site could yield a race with accesses later in this function}}
127+
await transferToNonIsolated(x) // expected-tns-warning {{transferring value of non-Sendable type '(NonSendableLinkedList<Int>, NonSendableLinkedList<Int>)' from global actor 'GlobalActor'-isolated context to nonisolated context; later accesses could race}}
128128
// expected-complete-warning @-1 {{passing argument of non-sendable type '(NonSendableLinkedList<Int>, NonSendableLinkedList<Int>)' outside of global actor 'GlobalActor'-isolated context may introduce data races}}
129129
// expected-complete-warning @-2 {{passing argument of non-sendable type '(NonSendableLinkedList<Int>, NonSendableLinkedList<Int>)' outside of global actor 'GlobalActor'-isolated context may introduce data races}}
130130

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// RUN: %target-swift-frontend -emit-sil -strict-concurrency=complete -enable-experimental-feature RegionBasedIsolation -disable-availability-checking -verify -verify-additional-prefix tns- %s -o /dev/null -parse-as-library
2+
3+
// Tests specific to global actors.
4+
5+
// REQUIRES: concurrency
6+
// REQUIRES: asserts
7+
8+
////////////////////////
9+
// MARK: Declarations //
10+
////////////////////////
11+
12+
class Klass {}
13+
14+
struct NonSendableStruct {
15+
var first = Klass()
16+
var second = Klass()
17+
}
18+
19+
func useValue<T>(_ t: T) {}
20+
func getAny() -> Any { fatalError() }
21+
22+
actor Custom {
23+
}
24+
25+
@globalActor
26+
struct CustomActor {
27+
static var shared: Custom {
28+
return Custom()
29+
}
30+
}
31+
32+
@MainActor func transferToMain<T>(_ t: T) {}
33+
@CustomActor func transferToCustom<T>(_ t: T) {}
34+
35+
@MainActor var globalKlass = Klass()
36+
37+
/////////////////
38+
// MARK: Tests //
39+
/////////////////
40+
41+
@MainActor func testTransferGlobalActorGuardedValue() async {
42+
await transferToCustom(globalKlass) // 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}}
43+
}
44+
45+
@MainActor func testTransferGlobalActorGuardedValueWithlet() async {
46+
let x = globalKlass
47+
await transferToCustom(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}}
48+
}
49+
50+
@MainActor func testTransferGlobalActorGuardedValueWithlet(_ k: Klass) async {
51+
globalKlass = k
52+
await transferToCustom(k) // 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}}
53+
}

0 commit comments

Comments
 (0)