Skip to content

verilog: a zero-length array is not a register of usize::MAX bits (Refs #2566) - #2605

Merged
gHashTag merged 1 commit into
masterfrom
fix/zero-length-array-width
Aug 23, 2026
Merged

verilog: a zero-length array is not a register of usize::MAX bits (Refs #2566)#2605
gHashTag merged 1 commit into
masterfrom
fix/zero-length-array-width

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

var notebooks : [0]Notebook is a legal empty list. The packed-array path computes total_width = dims[0] * elem_w — zero — and then total_width - 1 on a usize is 18446744073709551615:

reg [18446744073709551615:0] notebooks;

at exit 0, past every green gate. Two sites (1-D and multi-dimensional) clamped the way range_decl clamps.

650 specs regenerated: 1 file differs, and it is the target. Elaboration 176 vs baseline 176. Corpus ratchet clean. Ledger tightened 2 → 1.

The remaining entry is not a bug

Str { data: [4096]u8; len: u32 }                    = 4096*8 + 32     =    32,800
Map { keys: [64]Str; values: [64]Str; count: u32 }  = 2*64*32800 + 32 = 4,198,432

513 KiB in one packed register. The backend computed it faithfully; the spec asked for something with no hardware form. Whether a type that large should be lowerable is a design decision with a cost — filed with the same question about zero-width types, not decided here. The arithmetic now sits beside the ledger entry so the next reader does not look for a subtraction that is not there.

Three absurd widths, three unrelated mechanisms, two of them bugs. A gate that catches a class catches things outside the class it was written for; the discipline is to find the mechanism for each hit rather than assume the one already fixed.

On scope

Searching for this underflow turned up 96 sites formatting [{}:0] with a bare - 1, against 8 using saturating_sub. That is a candidate list, not a finding: exactly one of the 96 produces a bad width over the corpus, because the rest operate on widths that cannot be zero. Fixing 95 unverifiable sites in a compiler is a change nobody can defend later — the count is recorded, the claim is not.

§96 and §97.

Refs #2566

`var notebooks : [0]Notebook` is a legal empty list. The packed-array
path computes `total_width = dims[0] * elem_w`, which is 0, and then
`total_width - 1` on a usize is 18446744073709551615 -- emitted as

    reg [18446744073709551615:0] notebooks;

at exit 0, past every green gate (#2566). Two sites, the 1-D and the
multi-dimensional branch, clamped the way range_decl clamps: a one-bit
placeholder for a type that occupies none, which is a legal declaration
rather than an impossible one.

650 specs regenerated against master's binary: 1 file differs, and it
is the target. Elaboration 176 against baseline 176. Corpus ratchet
clean. Ledger tightened 2 -> 1.

THE REMAINING ENTRY IS NOT A BUG, and the arithmetic is now written
beside it:

    Str { data: [4096]u8; len: u32 }        = 4096*8 + 32     =    32,800
    Map { keys: [64]Str; values: [64]Str;
          count: u32 }                      = 2*64*32800 + 32 = 4,198,432

513 KiB in one packed register. The backend computed it faithfully; the
spec asked for something with no hardware form. Whether a type that
large should be lowerable is a design decision with a cost, and it is
filed with the same question about zero-width types rather than decided
here.

Three absurd widths, three unrelated mechanisms, two of them bugs. A
gate that catches a CLASS catches things outside the class it was
written for, and the discipline is to find the mechanism for each hit
rather than assume the one already fixed.

One more, on scope: searching for this underflow turned up 96 sites in
the compiler that format `[{}:0]` with a bare `- 1`, against 8 that use
saturating_sub. That is a candidate list, not a finding -- exactly one
of the 96 produces a bad width over the corpus, because the rest
operate on widths that cannot be zero. Fixing 95 unverifiable sites in
a compiler is a change nobody can defend later; the count is recorded,
the claim is not.

Refs #2566
@github-actions

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-08-23 20:54:41 UTC

Summary

Status Count
Total Open PRs 2
PRs with Failing Checks 1
PRs with All Checks Green 1
READY 0
FAILING 1
PENDING 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=e6333575ec10 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@gHashTag
gHashTag merged commit 6abe4d9 into master Aug 23, 2026
37 of 38 checks passed
@gHashTag
gHashTag deleted the fix/zero-length-array-width branch August 23, 2026 21:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant