swift icon indicating copy to clipboard operation
swift copied to clipboard

A simple concurrency safety breach of a var being captured by reference

Open CrystDragon opened this issue 1 year ago • 5 comments

Description

The following code compiles without warnings.

nonisolated  func f() async -> Int {
    var value = 0
    let task1 = Task { @MainActor in
        for _ in 0..<100000 {
            value += 1
        }
    }
    for _ in 0..<100000 {
        value += 1
    }
    await _ = task1.value
    return value
}

print(await f())

But it cannot produce 200000 because of the apparent race on value.

Also, for the following modified code, the compiler will complain "Pattern that the region based isolation checker does not understand how to check".

nonisolated func f() async -> Int {
    var value = 0
    let task1 = Task { @MainActor in
        for _ in 0..<100000 {
            value += 1
        }
    }
    let task2 = Task { @MainActor in
        for _ in 0..<100000 {
            value += 1
        }
    }
    await _ = task1.value
    await _ = task2.value
    return value
}

Reproduction

See above.

Expected behavior

  • There should be warnings/errors for the first example.
  • Solve "Pattern that the region based isolation checker does not understand how to check" for the second example.

Environment

  • Apple Swift version 6.0 (swiftlang-6.0.0.9.10 clang-1600.0.26.2)
  • Target: arm64-apple-macosx14.0
  • Version 16.0 (16A242d)

Additional information

No response

CrystDragon avatar Oct 09 '24 13:10 CrystDragon

This issue seems to be related to the problem I've described on Swift Forums

NSFatalError avatar Oct 12 '24 23:10 NSFatalError

Just tested this using the latest release/6.1 snapshot. There's still no diagnostics. Isn't this one a crucial regression? @hborla

CrystDragon avatar Dec 06 '24 06:12 CrystDragon

Status update after tested against the release/6.1 nightly build.

For the second code snippet, now the compiler can emit a error saying "Sending 'value' risks causing data races"

But for the first code snippet, the compiler still fails to produce any error. Note that if compiled using Swift 5.9, there will be an error. in Swift 5.9.

@ktoso Forgive my ignorance, but don't you agree this a particular naive bad case? Are there any underlying complexities that make this one so hard to address?

CrystDragon avatar Jan 14 '25 07:01 CrystDragon

I would argue that in most Swift Concurrency cases, from a developer's view, "a false positive" could be a better option compared to "a false negative". Personally I'd rather choose to be limited while free-of-error than to be uncertain of correctness.

CrystDragon avatar Jan 14 '25 07:01 CrystDragon

Yes, this is a data-race safety hole that needs to be fixed. It's a bug in region based isolation.

hborla avatar Mar 27 '25 03:03 hborla

The nightly build can now correctly emit diagnostics for the 2 code snippets in OP. Good work!

CrystDragon avatar May 28 '25 06:05 CrystDragon