Regex: Inconsistent atomic access
lorentey opened this issue · 0 comments
lorentey commented
In Regex/Core.swift
, we have the following code:
/// The program for execution with the matching engine.
var loweredProgram: MEProgram {
if let loweredObject = _loweredProgramStorage as? ProgramBox {
return loweredObject.value
}
let lowered = try! Compiler(tree: tree, compileOptions: compileOptions).emit()
_stdlib_atomicInitializeARCRef(object: &_loweredProgramStorage, desired: ProgramBox(lowered))
return lowered
}
This allows regular non-atomic loads of the _loweredProgramStorage
variable to occur concurrently with atomic updates (cmpxchg) of it. This is explicitly undefined behavior per the Law of Exclusivity:
Two accesses to the same variable aren't allowed to overlap unless both accesses are reads or both accesses are atomic. -- SE-0282
We must avoid such accesses by converting the nonatomic load into an atomic load instruction:
if let ref = _stdlib_atomicLoadARCRef(object: &_loweredProgramStorage) {
return unsafeDowncast(ref, to: ProgramBox.self)
}
On a secondary note, in case the current thread loses a concurrent update race, this property ought to return the winner program box, not the loser.