Skip to content

Regex: Inconsistent atomic access #609

Closed
@lorentey

Description

@lorentey

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions