Skip to content

Commit c50e171

Browse files
committed
[region-isolation] Ensure that global actor guarded globals are treated as being actor specific state.
So for instance, one cannot transfer them, just like actor state.
1 parent 5f1b488 commit c50e171

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

lib/SILOptimizer/Analysis/RegionAnalysis.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2833,6 +2833,15 @@ TrackableValue RegionAnalysisValueMap::getTrackableValue(
28332833
iter.first->getSecond().addFlag(TrackableValueFlag::isActorDerived);
28342834
}
28352835
}
2836+
2837+
// See if the memory base is a global_addr from a global actor protected global.
2838+
if (auto *ga = dyn_cast<GlobalAddrInst>(storage.base)) {
2839+
if (auto *global = ga->getReferencedGlobal()) {
2840+
if (getActorIsolation(global->getDecl()).isGlobalActor()) {
2841+
iter.first->getSecond().addFlag(TrackableValueFlag::isActorDerived);
2842+
}
2843+
}
2844+
}
28362845
}
28372846
}
28382847

test/Concurrency/transfernonsendable_strong_transferring.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,19 @@ struct NonSendableStruct {
1515

1616
func useValue<T>(_ t: T) {}
1717
func getAny() -> Any { fatalError() }
18+
19+
actor Custom {
20+
}
21+
22+
@globalActor
23+
struct CustomActor {
24+
static var shared: Custom {
25+
return Custom()
26+
}
27+
}
28+
1829
@MainActor func transferToMain<T>(_ t: T) {}
30+
@CustomActor func transferToCustom<T>(_ t: T) {}
1931

2032
func transferArg(_ x: transferring Klass) {
2133
}
@@ -115,11 +127,27 @@ actor MyActor {
115127
globalKlass = x
116128
}
117129

130+
@MainActor func canAssignTransferringIntoGlobalActor2(_ x: transferring Klass) async {
131+
globalKlass = x
132+
await transferToCustom(x) // expected-warning {{call site passes `self` or a non-sendable argument of this function to another thread, potentially yielding a race with the caller}}
133+
}
134+
135+
@MainActor func canAssignTransferringIntoGlobalActor3(_ x: transferring Klass) async {
136+
await transferToCustom(globalKlass) // expected-warning {{call site passes `self` or a non-sendable argument of this function to another thread, potentially yielding a race with the caller}}
137+
}
138+
118139
func canTransferAssigningIntoLocal(_ x: transferring Klass) async {
119140
let _ = x
120141
await transferToMain(x)
121142
}
122143

144+
func canTransferAssigningIntoLocal2(_ x: transferring Klass) async {
145+
let _ = x
146+
await transferToMain(x) // expected-warning {{passing argument of non-sendable type 'Klass' from nonisolated context to main actor-isolated context at this call site could yield a race with accesses later in this function}}
147+
let _ = x // expected-note {{access here could race}}
148+
}
149+
150+
123151
//////////////////////////////////////
124152
// MARK: Transferring is "var" like //
125153
//////////////////////////////////////

0 commit comments

Comments
 (0)