Skip to content

Commit 96ee7a0

Browse files
committed
[Sema]: Fix data race safety hole with mutable statics within actors
Update the concurrency typechecking logic to remove a check that allowed mutable static variable declarations nested within an Actor type to be ignored when diagnosing mutable non-Sendable state.
1 parent afb4d13 commit 96ee7a0

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6202,9 +6202,7 @@ void swift::checkGlobalIsolation(VarDecl *var) {
62026202
var->getASTContext().LangOpts.hasFeature(Feature::GlobalConcurrency) &&
62036203
!isolation.isGlobalActor() &&
62046204
(isolation != ActorIsolation::NonisolatedUnsafe)) {
6205-
auto *classDecl = var->getDeclContext()->getSelfClassDecl();
6206-
const bool isActorType = classDecl && classDecl->isAnyActor();
6207-
if (var->isGlobalStorage() && !isActorType) {
6205+
if (var->isGlobalStorage()) {
62086206
auto *diagVar = var;
62096207
if (auto *originalVar = var->getOriginalWrappedProperty()) {
62106208
diagVar = originalVar;

test/Concurrency/global_variables.swift

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
@globalActor
1010
actor TestGlobalActor {
11-
static var shared = TestGlobalActor()
11+
static let shared = TestGlobalActor()
1212
}
1313

1414
@TestGlobalActor
@@ -72,6 +72,38 @@ struct TestStatics {
7272
public actor TestPublicActor {
7373
nonisolated(unsafe) let immutableNonisolatedUnsafeSendable = TestSendable()
7474
// expected-warning@-1 {{'(unsafe)' is unnecessary for a constant public actor property with 'Sendable' type 'TestSendable', consider removing it}} {{14-22=}}
75+
76+
// https://github.com/swiftlang/swift/issues/78435
77+
static var actorStatic = 0
78+
// expected-error@-1 {{static property 'actorStatic' is not concurrency-safe because it is nonisolated global shared mutable state}}
79+
// expected-note@-2{{convert 'actorStatic' to a 'let' constant to make 'Sendable' shared state immutable}}{{10-13=let}}
80+
// expected-note@-3{{disable concurrency-safety checks if accesses are protected by an external synchronization mechanism}}{{3-3=nonisolated(unsafe) }}
81+
// expected-note@-4{{add '@MainActor' to make static property 'actorStatic' part of global actor 'MainActor'}}{{3-3=@MainActor }}
82+
}
83+
84+
enum EnumSpace {
85+
static let enumStaticLet = TestSendable()
86+
87+
static var enumStatic = 0
88+
// expected-error@-1 {{static property 'enumStatic' is not concurrency-safe because it is nonisolated global shared mutable state}}
89+
// expected-note@-2{{convert 'enumStatic' to a 'let' constant to make 'Sendable' shared state immutable}}{{10-13=let}}
90+
// expected-note@-3{{disable concurrency-safety checks if accesses are protected by an external synchronization mechanism}}{{3-3=nonisolated(unsafe) }}
91+
// expected-note@-4{{add '@MainActor' to make static property 'enumStatic' part of global actor 'MainActor'}}{{3-3=@MainActor }}
92+
}
93+
94+
@TestGlobalActor
95+
enum IsolatedEnumSpace {
96+
static let inferredGlobalActorStaticLet = TestSendable()
97+
98+
static var inferredGlobalActorStatic = 0
99+
}
100+
101+
public actor GlobalActorComputed: GlobalActor {
102+
static let storage = GlobalActorComputed()
103+
104+
public static var shared: GlobalActorComputed {
105+
Self.storage
106+
}
75107
}
76108

77109
@TestGlobalActor

0 commit comments

Comments
 (0)