diff --git a/bootstrap/src/compiler.rs b/bootstrap/src/compiler.rs index f87a89367b..ef612cb743 100644 --- a/bootstrap/src/compiler.rs +++ b/bootstrap/src/compiler.rs @@ -15420,7 +15420,13 @@ impl VerilogCodegen { } NodeKind::StmtForRange | NodeKind::StmtWhile - | NodeKind::StmtFor => { + // t27#1948's comment below names `for`/`while`/`if`, and `if` + // was never in this arm. `if (es_prestandard(8) != 0) { ok = + // false; }` at the top level of a test block became + // `// (stmt: StmtIf)`, so `ok` was set true and never set + // false: the test could not fail and reported PASSED. + | NodeKind::StmtFor + | NodeKind::StmtIf => { self.materialize_call_array_tmps_in_expr(node); self.gen_verilog_stmt(node); } @@ -15540,7 +15546,8 @@ impl VerilogCodegen { } NodeKind::StmtForRange | NodeKind::StmtWhile - | NodeKind::StmtFor => { + | NodeKind::StmtFor + | NodeKind::StmtIf => { // Control flow in a test block: a `for`/`while`/`if` was // dropped as `// (stmt: StmtForRange)`, silently voiding // loop bodies that accumulate assertions (t27#1948). @@ -15563,7 +15570,11 @@ impl VerilogCodegen { "// invariant {} : ", Self::sanitize_identifier(&node.name) )); - self.gen_verilog_expr(&node.children[0]); + // The predicate arrives wrapped in a statement node, and the + // expression printer answers `/* unsupported expr: StmtExpr */`. + // All 4702 invariants in the self-checking testbench rendered that + // and not one rendered a predicate. + self.gen_verilog_expr(unwrap_single(&node.children[0])); self.write_line(""); } else { self.write_line(&format!("// invariant: {}", node.name)); diff --git a/bootstrap/stage0/FROZEN_HASH b/bootstrap/stage0/FROZEN_HASH index 3f6eb71f65..7e33d10417 100644 --- a/bootstrap/stage0/FROZEN_HASH +++ b/bootstrap/stage0/FROZEN_HASH @@ -1 +1 @@ -b109d745f01460f08fb2f8547d27a816dfecaff6c3f917da90f2f465c3daa86d +6e3be54a2bd0d899ec680c429be131b9cbf4a857d7bbb578870dbe16dd01b132 diff --git a/docs/now/2026-08-30-the-comment-named-if-and-the-arm-did-not.md b/docs/now/2026-08-30-the-comment-named-if-and-the-arm-did-not.md new file mode 100644 index 0000000000..3ba1ebc536 --- /dev/null +++ b/docs/now/2026-08-30-the-comment-named-if-and-the-arm-did-not.md @@ -0,0 +1,10 @@ +# NOW -- The comment named `if` and the match arm did not (2026-08-30) + +## Two ways the self-checking testbench stopped checking (Refs #2869) + +- `if (es_prestandard(8) != 0) { ok = false; }` at the TOP LEVEL of a test block became `// (stmt: StmtIf)`, so `ok` was set true and never set false: the test could not fail and reported PASSED +- the match arm handles StmtForRange / StmtWhile / StmtFor, and the comment directly under it says "a `for`/`while`/`if` was dropped" -- `if` was written down and never added +- 11 statements in 2 specs; neither simulates today for unrelated reasons, so no verdict changes now and the class is what closes +- separately: ALL 4702 invariants in the self-checking testbench rendered their predicate as `/* unsupported expr: StmtExpr */`, because the predicate arrives wrapped in a statement node +- unwrapping it -- the same `unwrap_single` the `while` fix needed -- renders 4697 of the 4702; five are genuinely unsupported +- corrected against the audit: the 5635 comments in synthesizable RTL are a MANIFEST, and the header above them says so. Those are a declared omission, not a hidden one. The defect is in the SIMULATION path, which is smaller and worse