Skip to content

Commit 69a2011

Browse files
committed
[Concurrency] Fix null pointer dereference for task-to-thread model.
In task-to-thread concurrency mode, `_getMainExecutorAsSerialExecutor` returns `SerialExecutorRef::generic()`, which is, give or take, NULL. Unfortunately we'd declared it as returning `any SerialExecutor`, rather than `(any SerialExecutor)?`, and then the `getMainExecutor()` function was calling `asUnownedSerialExecutor()` on it, which then crashes. rdar://153152063
1 parent 665515c commit 69a2011

File tree

2 files changed

+7
-3
lines changed

2 files changed

+7
-3
lines changed

stdlib/public/Concurrency/ExecutorBridge.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,14 @@ internal func _jobGetExecutorPrivateData(
9191
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
9292
@available(StdlibDeploymentTarget 6.2, *)
9393
@_silgen_name("swift_getMainExecutor")
94-
internal func _getMainExecutor() -> any SerialExecutor {
94+
internal func _getMainExecutorAsSerialExecutor() -> (any SerialExecutor)? {
9595
return MainActor.executor
9696
}
9797
#else
9898
// For task-to-thread model, this is implemented in C++
9999
@available(StdlibDeploymentTarget 6.2, *)
100100
@_silgen_name("swift_getMainExecutor")
101-
internal func _getMainExecutor() -> any SerialExecutor
101+
internal func _getMainExecutorAsSerialExecutor() -> (any SerialExecutor)?
102102
#endif // SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
103103
#endif // !$Embedded
104104

stdlib/public/Concurrency/ExecutorImpl.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ internal func donateToGlobalExecutor(
4747
@available(SwiftStdlib 6.2, *)
4848
@_silgen_name("swift_task_getMainExecutorImpl")
4949
internal func getMainExecutor() -> UnownedSerialExecutor {
50-
return unsafe _getMainExecutor().asUnownedSerialExecutor()
50+
let executor = _getMainExecutorAsSerialExecutor()
51+
if let executor {
52+
return unsafe executor.asUnownedSerialExecutor()
53+
}
54+
return unsafe unsafeBitCast(executor, to: UnownedSerialExecutor.self)
5155
}
5256

5357
@available(SwiftStdlib 6.2, *)

0 commit comments

Comments
 (0)