selfhost/cmd+test: run check before cgen in wwstage drivers

w6c_ww and wwdump_ww (-c mode) silently passed source into cgen
without type-checking it; any type error flowed through as broken
asm with exit 0. Mirror cstage cmd/w6c/main.c:73-75: between the
parse-error gate and cgeninit, install typesinit + checkinit +
checkfile + `if (ck.errs > 0) return 1;`. Cgen path unchanged —
drivers own check, cgen owns emit (checkfile not idempotent due to
installdecl scopedefine).

The wire-up was blocked by five latent check.ww divergences from
cstage, all landed first: cross-module type refs (#51), enum-int
reinterprets (#52), per-block scoping (#53), nominal-first
tagged-variant inclusion (#55), and same-module N_IDENT callee
preference (#56). With those clear, the broader exercise of
check across every selfhost driver reaches 131/131 first try.

994_w6c_ww grows by one row: a trivially-wrong `let x: i32 =
"hello";` smoke pins both stages to exit-non-zero. Pre-#50 it
emitted 202 bytes of broken asm with exit=0.

Unblocks #42 (size/align/offset wwstage intercepts) and the
audit-§1.8 UP-polarity refactor (node.type_ population can now
land in the same check pass we just wired up).
This commit is contained in:
2026-05-20 04:52:16 +09:00
parent 3fa5ccd5ae
commit c58d3511e8
5 changed files with 87 additions and 0 deletions

View File

@@ -22442,6 +22442,19 @@ export fn main(argc: i32, argv: **u8) i32 = {
// cgen and emits junk asm with a zero exit (silent miscompile).
if (l.errs > 0 || ps.errs > 0) { return 1; };
// #50: run check before cgen so AST mutations from #42 (size/align/
// offset fold) and the audit §1.8 node.type_ population land before
// cgen walks the file. Mirrors cmd/w6c/main.c:73-75. Five precondition
// fixes for fixture cleanliness: #51 cross-module type refs, #52
// enum↔int reinterpret, #53 N_BLOCK scoping, #55 nominal-first variant
// compare, #56 bare-leaf same-module preference.
let tc: tctx;
typesinit(&tc, ar);
let ck: checker;
checkinit(&ck, ar, &tc);
checkfile(&ck, f);
if (ck.errs > 0) { return 1; };
let cg: cgen;
cgeninit(&cg, ar);
cgfile(&cg, f);

View File

@@ -147,6 +147,19 @@ export fn main(argc: i32, argv: **u8) i32 = {
// cgen and emits junk asm with a zero exit (silent miscompile).
if (l.errs > 0 || ps.errs > 0) { return 1; };
// #50: run check before cgen so AST mutations from #42 (size/align/
// offset fold) and the audit §1.8 node.type_ population land before
// cgen walks the file. Mirrors cmd/w6c/main.c:73-75. Five precondition
// fixes for fixture cleanliness: #51 cross-module type refs, #52
// enum↔int reinterpret, #53 N_BLOCK scoping, #55 nominal-first variant
// compare, #56 bare-leaf same-module preference.
let tc: tctx;
typesinit(&tc, ar);
let ck: checker;
checkinit(&ck, ar, &tc);
checkfile(&ck, f);
if (ck.errs > 0) { return 1; };
let cg: cgen;
cgeninit(&cg, ar);
cgfile(&cg, f);

View File

@@ -22454,6 +22454,17 @@ export fn main(argc: i32, argv: **u8) i32 = {
let ps: parser;
parserinit(&ps, a, &l);
let f: *node = parsefile(&ps);
// #50: mirror w6c — run check before cgen so AST mutations
// from #42 (size/align/offset fold) and audit §1.8 (node.type_
// population) land before cgen walks. Without this, wwdump -c
// (the byte-identity probe for 994) would diverge from w6c_ww
// on any program that uses the size/align/offset typed builtins.
let tc: tctx;
typesinit(&tc, a);
let ck: checker;
checkinit(&ck, a, &tc);
checkfile(&ck, f);
if (ck.errs > 0) { return 1; };
let cg: cgen;
cgeninit(&cg, a);
cgfile(&cg, f);

View File

@@ -159,6 +159,17 @@ export fn main(argc: i32, argv: **u8) i32 = {
let ps: parser;
parserinit(&ps, a, &l);
let f: *node = parsefile(&ps);
// #50: mirror w6c — run check before cgen so AST mutations
// from #42 (size/align/offset fold) and audit §1.8 (node.type_
// population) land before cgen walks. Without this, wwdump -c
// (the byte-identity probe for 994) would diverge from w6c_ww
// on any program that uses the size/align/offset typed builtins.
let tc: tctx;
typesinit(&tc, a);
let ck: checker;
checkinit(&ck, a, &tc);
checkfile(&ck, f);
if (ck.errs > 0) { return 1; };
let cg: cgen;
cgeninit(&cg, a);
cgfile(&cg, f);