swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.26k stars 10.33k forks source link

[SR-5662] false exclusive / simultaneous access crash with global tuple #48232

Open mattneub opened 7 years ago

mattneub commented 7 years ago
Previous ID SR-5662
Radar None
Original Reporter @mattneub
Type Bug
Environment Xcode Version 9.0 beta 5 (9M202q)
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: ea31295ccd833d6e426db6830442e9cd

Issue Description:

This crashes, but only when the tuple is a global variable (not when it is a local variable):

var globaltuple = (first:2, second:3)

class ViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        func swapInts(_ a: inout Int, _ b: inout Int) {
            let temp = a;
            a = b;
            b = temp;
        }

        var tuple = (first:2, second:3)
        swapInts(&tuple.first, &tuple.second) // no problem
        swapInts(&globaltuple.first, &globaltuple.second) // crash
        // Simultaneous accesses to 0x1000050a8, but modification requires exclusive access.

        // Do any additional setup after loading the view.
    }
}

See https://stackoverflow.com/questions/45559168/swift-4-simultaneous-access-to-tuple-members-as-inout. The inconsistency seems like a bug. This would also appear to be a false crash, because access to different tuple members should not count as a simultaneous access issue.

belkadan commented 7 years ago

@devincoughlin, @rjmccall, is this a bug?

devincoughlin commented 7 years ago

This is by design. An access to a part of a struct or a part of a tuple is an access to the whole value. In some limited circumstances where the compiler can prove it is safe, we don't warn. In this case the compiler can prove that accessing 'tuple' is safe because it is a local variable that isn't captured by an escaping closure. But since 'globalTuple' is a global it can't prove this is safe.

If you want to independently access stored properties, you should use a class.

mattneub commented 7 years ago

But what about the fact that the compiler doesn't warn? (We crash at runtime instead.) Is that a bug?

devincoughlin commented 7 years ago

The compiler only promises to make a "best effort" to warn at compile time for globals and classes, so in general this kind of thing is not a bug. However, in this case I do think it is reasonable to expect the compiler to warn you that this will definitely trap at run time.

To do this we could teach the compile-time exclusivity diagnostic machinery about mutable addressors for globals. Then, for accesses to addresses that come from global addressors we would not use the projected subpath and instead treat the access as an access to the whole.

mattneub commented 7 years ago

Okay, thanks, I've noted this in the original Stack Overflow question.