Skip to content

PHIR classical registers with size 0 are accepted outside the schema and silently zero or sign-fill writes #1348

Open

Description

@ciaranra

A classical register declared with "size": 0 is accepted by every PHIR path that does not run the pydantic schema. Writes into it then give silently wrong values. The upstream PHIR schema (size: PositiveInt | None), and so PhirModel.model_validate, rejects the declaration.

Reproduction

The native results below come from the #1314 branch. The size handling involved is the same on dev: Environment::validate_variable_size in crates/pecos-phir-json/src/v0_1/environment.rs (~578 on dev) has no zero check.

src = {"format": "PHIR/JSON", "version": "0.1.0", "ops": [
    {"data": "cvar_define", "data_type": "u32", "variable": "a", "size": 0},
    {"cop": "=", "args": [5], "returns": ["a"]},
    {"cop": "Result", "args": ["a"], "returns": ["out"]},
]}
Path u32, size 0 i32, size 0
pecos_rslib.run_phir_sim (native, no schema) {'out': ['']} {'out': ['1']}
HybridEngine, Rust interpreter, phir_validate=False a = 0, out = 0 a = -1, out = -1
HybridEngine, Python interpreter, phir_validate=False a = 0, out = 0 a = -1, out = -1
PhirModel.model_validate ValidationError ValidationError

a = 5 silently becomes 0 for unsigned registers. For signed registers it becomes -1: a signed size-S register is i(S+1), so size 0 keeps only the sign bit. A measurement into a[0] does fail, with "out of range for a register of declared size 0". The JSON-to-module converter was not checked.

Direction

Reject a classical size of 0 in the shared declaration validation, so every path agrees with the schema. Use a named error ("use a positive integer size that fits the data type"). Add a parity test over native, both interpreters (validation on and off) and the converter. The quantum side already rejects size 0.

Found during the review of the #1314 work.

Activity

  1. added
    bugSomething isn't working
    rustPull requests that update rust code
    severity:criticalSilently wrong results, data loss, or security exposure
    on Oct 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingrustPull requests that update rust codeseverity:criticalSilently wrong results, data loss, or security exposure

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions