Skip to content

The comment named if, and the match arm did not - #2871

Merged
gHashTag merged 1 commit into
masterfrom
w725
Aug 29, 2026
Merged

The comment named if, and the match arm did not#2871
gHashTag merged 1 commit into
masterfrom
w725

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

Two ways the self-checking testbench stopped checking. Takes the largest item from #2869, and corrects that issue's framing along the way.

1. A StmtIf at the top level of a test block was dropped

spec      test posit_prestandard_es_schedule
              var ok = true
              if (es_prestandard(8)   != 0) { ok = false; }
              ... four more ...
              then ok == true

emitted   ok = 1'b1;
          // (stmt: StmtIf)
          // (stmt: StmtIf)
          // (stmt: StmtIf)
          // (stmt: StmtIf)
          // (stmt: StmtIf)
          if (!((ok == 1'b1))) begin
              $display("[TEST] posit_prestandard_es_schedule : FAILED");

ok is set true and never set false. The test cannot fail, and reports PASSED.

The match arm covers StmtForRange | StmtWhile | StmtFor. The comment directly under it reads:

Control flow in a test block: a for/while/if was dropped as // (stmt: StmtForRange), silently voiding loop bodies that accumulate assertions (t27#1948).

if is named in the sentence and was never in the arm.

11 statements across 2 specs. Neither simulates today — both fail elaboration for unrelated reasons — so no test verdict changes now. What closes is the class.

2. Every invariant predicate in the testbench was unsupported expr

All 4702 invariants in the self-checking testbench rendered as:

// invariant debounce_delay_is_phi_inv : /* unsupported expr: StmtExpr */

The predicate arrives wrapped in a statement node. The same unwrap_single the while repair needed renders 4697 of the 4702:

// invariant debounce_delay_is_phi_inv : (DEBOUNCE_DELAY_MS == 618)
// invariant gf16_sign_mask_bit_position : (SIGN_MASK == 32768)

Five are genuinely unsupported.

A correction to #2869

That issue says the invariants reach the testbench as comments "under a section header that calls them checks". The 5635 comments in synthesizable RTL are a manifest, and the header above them says the opposite — that these are simulation constructs carried by gen-verilog-for-simulation. That is a declared omission, not a hidden one.

The real defect is in the simulation path: smaller (4702, not 5635) and worse, because that command's whole purpose is to check.

They are still comments. Making them run is a further step and a larger blast radius; rendering the predicate is the prerequisite and is what this does.

before after
dropped StmtIf in testbenches 11 0
invariant predicates rendered 0 / 4702 4697 / 4702
testbench iverilog acceptance 372 / 559 372 / 559
suite 2455 / 0 2455 / 0

bootstrap/stage0/FROZEN_HASH resealed.

Refs #2869

Two ways the self-checking testbench stopped checking.

FIRST. A `StmtIf` at the top level of a test block was dropped:

    spec      test posit_prestandard_es_schedule
                  var ok = true
                  if (es_prestandard(8)  != 0) { ok = false; }
                  ... four more ...
                  then ok == true

    emitted   ok = 1'b1;
              // (stmt: StmtIf)     x5
              if (!((ok == 1'b1))) begin
                  $display("[TEST] ... : FAILED");

`ok` is set true and never set false. The test cannot fail, and reports
PASSED.

The match arm covers `StmtForRange | StmtWhile | StmtFor`, and the
comment directly under it reads: "Control flow in a test block: a
`for`/`while`/`if` was dropped as `// (stmt: StmtForRange)`, silently
voiding loop bodies that accumulate assertions (t27#1948)." `if` is
named in the sentence and was never in the arm.

11 statements across 2 specs. Neither simulates today -- both fail
elaboration for unrelated reasons -- so no test verdict changes now;
what closes is the class.

SECOND. Every one of the 4702 invariants in the self-checking testbench
rendered its predicate as `/* unsupported expr: StmtExpr */`, because
the predicate arrives wrapped in a statement node. The same
`unwrap_single` the `while` repair needed renders 4697 of them:

    // invariant debounce_delay_is_phi_inv : (DEBOUNCE_DELAY_MS == 618)

Five are genuinely unsupported.

A correction to the audit that prompted this: the 5635 `// invariant`
lines in SYNTHESIZABLE RTL are a manifest, and the header above them
says these are simulation constructs carried by
`gen-verilog-for-simulation`. That is a declared omission, not a hidden
one. The defect is in the simulation path, which is smaller and worse.

Testbench iverilog acceptance and suite unchanged.

FROZEN_HASH resealed.

Refs #2869
@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-29 19:22:56 UTC

Summary

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

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=6e3be54a2bd0 != 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 074f5dc into master Aug 29, 2026
26 of 27 checks passed
gHashTag added a commit that referenced this pull request Aug 29, 2026
)

312: a match arm covers `StmtForRange | StmtWhile | StmtFor` and the
comment directly under it says "a `for`/`while`/`if` was dropped". `if`
is in the sentence and not in the pattern. A top-level `if` in a test
block therefore became `// (stmt: StmtIf)`, the flag was set true and
never false, and the test reported PASSED. When a comment enumerates
cases, the list is checkable against the arm in one glance.

313: my first probe of that finding read the wrong spec --
`lucas_accumulator.t27` nests its `if` inside a `while`, which routes
through a path that handles it -- and I nearly recorded a true report as
not reproducing. The claim said TOP-LEVEL `if`; I tested an `if`. When a
report names a position, the position is part of the claim, and ignoring
it produces a confident refutation rather than a missed defect.

Refs #2871
gHashTag added a commit that referenced this pull request Aug 29, 2026
The PR body carried no `Refs`, so `check-linked-issue` and
`Check L1 TRACEABILITY` were both red -- law L1 requires every change to
name the issue it belongs to, and I wrote a PR about a detector for
"the comment claims something the code does not" without linking it to
either defect it was written after.

Refs #2844, #2871
gHashTag added a commit that referenced this pull request Aug 29, 2026
)

* tri kinds drift: the arm's comment names a case the pattern omits

In two passes the same defect was found four times, in four emitters,
and every one is a fixed list of node kinds with a case absent:

    Verilog test-block statements   StmtIf           a test that could not fail
    Rust has_body                   StmtAssign       53 functions became a stub
    Rust expr_is_bool               ExprFieldAccess  !x.flag became (x.flag)==0
    compound_binop                  /=               x /= 2 became x = 2

None is a subtle algorithm. Each is one identifier absent from a
`matches!`, and two of the four are findable mechanically, because the
comment beside the arm ENUMERATES the cases and the pattern does not
match the enumeration:

    NodeKind::StmtForRange | NodeKind::StmtWhile | NodeKind::StmtFor => {
        // Control flow in a test block: a `for`/`while`/`if` was dropped

`if` is in the sentence and not in the pattern. That is a diff, not a
judgement.

The command reads the comment INSIDE an arm's body, never the one above
its pattern: a comment above belongs to the previous arm as often as to
this one, and reading it as this arm's claim hits every second arm in
the file. That is a test.

Silent on master, and it says so rather than printing nothing: "Zero is
a result here and not a silence: 57 arms were read and each one's
comment was compared against its own pattern."

Historical control: run against the commit before #2871 it reports
exactly one arm, `StmtForRange | StmtWhile | StmtFor` missing `StmtIf` --
the defect it was written after, on the commit where it still existed.

The word `assignment` unquoted was in the vocabulary and produced two
hits on master, both prose. Requiring the backtick took the false
positives to zero and left the control firing.

5 tests. Skill sections 317-318.

* tri kinds drift: name the issues this follows

The PR body carried no `Refs`, so `check-linked-issue` and
`Check L1 TRACEABILITY` were both red -- law L1 requires every change to
name the issue it belongs to, and I wrote a PR about a detector for
"the comment claims something the code does not" without linking it to
either defect it was written after.

Refs #2844, #2871
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