PR-9995: enable exclusivity runtime checks.

Hi swift-dev,

PR-9995 enables exclusivity runtime checks:

These checks catch violations of exclusivity that can't be discovered statically [0], printing the message:

"Simultaneous accesses to 0x*, but modification requires exclusive access."

The error message is followed by a backtrace and details on the source locations of the two conflicting accesses.

In Swift 3 mode, this runtime diagnostic is a warning. In Swift 4 mode it is an error, meaning the program aborts immediately after reporting the first failure.

To disable the runtime checks, use -enforce-exclusivity=unchecked, which enables static
checks only.

This feature is explained in the Swift evolution proposal: Enforce Exclusive Access to Memory:

Note that exclusivity is not yet fully enforced for noescape closures. The current checks are conservative in this respect. Enforcement will be strengthened to handle this case in the near future, pending review of the proposal ammendment: "Restrictions on recursive uses of non-escaping closures".

[0] dynamic exclusivity violation

struct MyStruct {
  var i: Int = 0

  mutating func mutateS(_ f: ()->Int) {
    i += f()
  }
}

class MyClass {
  var s: MyStruct
  
  init() { s = MyStruct() }
}

func foo(_ o: MyClass) {
  o.s.mutateS({ o.s.i })
}

-Andy

Runtime checks only take effect at -Onone. Even if you explicitly ask for checks via -enforce-exclusivity=checked, they will be stripped (with a warning from the driver).

Support for dynamic checking at -O is something that will be considered post Swift 4.

-Andy

···

On Jun 1, 2017, at 4:47 PM, Andrew Trick <atrick@apple.com> wrote:

Hi swift-dev,

PR-9995 enables exclusivity runtime checks:
[Exclusivity] Enable dynamic checks by default at -Onone. by atrick · Pull Request #9995 · apple/swift · GitHub

These checks catch violations of exclusivity that can't be discovered statically [0], printing the message:

"Simultaneous accesses to 0x*, but modification requires exclusive access."

The error message is followed by a backtrace and details on the source locations of the two conflicting accesses.

In Swift 3 mode, this runtime diagnostic is a warning. In Swift 4 mode it is an error, meaning the program aborts immediately after reporting the first failure.

To disable the runtime checks, use -enforce-exclusivity=unchecked, which enables static
checks only.

This feature is explained in the Swift evolution proposal: Enforce Exclusive Access to Memory:
https://github.com/apple/swift-evolution/blob/master/proposals/0176-enforce-exclusive-access-to-memory.md

Note that exclusivity is not yet fully enforced for noescape closures. The current checks are conservative in this respect. Enforcement will be strengthened to handle this case in the near future, pending review of the proposal ammendment: "Restrictions on recursive uses of non-escaping closures".
https://github.com/apple/swift-evolution/blob/master/proposals/0176-enforce-exclusive-access-to-memory.md#restrictions-on-recursive-uses-of-non-escaping-closures

[0] dynamic exclusivity violation

struct MyStruct {
var i: Int = 0

mutating func mutateS(_ f: ()->Int) {
   i += f()
}
}

class MyClass {
var s: MyStruct

init() { s = MyStruct() }
}

func foo(_ o: MyClass) {
o.s.mutateS({ o.s.i })
}

-Andy