diff --git a/test/run b/test/run index d5f866c1..67f8af4e 100755 --- a/test/run +++ b/test/run @@ -187,25 +187,6 @@ if [ "${UNIT:-0}" != "1" ]; then done | xargs -0 -n2 -P "$JOBS" "$0" --one || true p2par_end=$(date +%s.%N) fi - - # combined.ww freshness gate (#110): 990/995 above unconditionally - # regenerate every tracked combined.ww amalgamation, so a diff vs HEAD - # here means an embedded source changed without its derived artifact - # being regenerated + committed (the #28 staleness hole the per-file - # byte-id gates were blind to). git ls-files keeps new combined.ww - # auto-covered (rule-13 SSoT). Lives inside the UNIT guard because - # test-unit skips 990/995 and thus the regen. - name=combined_ww_fresh - if git diff --exit-code -- $(git ls-files '*.combined.ww') > /dev/null 2>&1; then - printf 'ok %s\n' "$name" > "$RESULTS/$name.status" - else - { - printf 'FAIL %s (stale; regen + commit the derived amalgamation)\n' "$name" - echo '--- stale combined.ww ---' - git diff --name-only -- $(git ls-files '*.combined.ww') - } > "$RESULTS/$name.status" - : > "$RESULTS/$name.fail" - fi fi fail=0 diff --git a/test/wcc/990_selfhost.c b/test/wcc/990_selfhost.c index 65f4333a..e522f51e 100644 --- a/test/wcc/990_selfhost.c +++ b/test/wcc/990_selfhost.c @@ -518,21 +518,21 @@ cleanup: } /* resolveunit — produce 's RESOLVED translation unit the way - * the driver does. `ww build` concatenates the module with its - * transitive imports into .combined.ww (cmd/ww/main.c expand()), - * which is the single unit w6c/wwdump actually consume; w6c never - * resolves imports itself (cmd/w6c/main.c reads one pre-concatenated - * file). Feeding a raw module file therefore leaves its import refs - * (os.write, fmt.errorln, strconv.i64tos …) unresolved — a partial - * unit harec's module::resolve never hands the checker, and which the - * ww-stage asserttyped invariant (check.ww) is not meant to see. + * the sep driver does. `ww build --sep` composes the root package's + * .sepwork/__root.unit.ww: the transitive deps' `.wwi` interface + * stubs followed by the root package body — the single self-contained + * unit w6c/wwdump consume for the root (the producer compiles it with no + * -I; cmd/ww/main.c sep_compose_unit). Feeding a raw module file instead + * would leave its import refs (os.write, fmt.errorln, strconv.i64tos …) + * unresolved — a partial unit harec's module::resolve never hands the + * checker, and which the ww-stage asserttyped invariant must not see. * - * Built in a private /tmp dir (a copy of the fixture) so no .combined.ww - * / .s / .o lands next to the repo source. The link step fails for an - * import-only module (no main), but .combined.ww is written before - * codegen, so we detect that artifact rather than gating on the build - * exit. Writes the owning tmpdir into `td` (caller rm -rf's it) and the - * combined path into `out`. Returns 0 on success, -1 otherwise. */ + * Built in a private /tmp dir (a copy of the fixture) so the sepwork + * lands off the repo source tree. The link step fails for an import-only + * module (no main), but the unit is written before the link, so we detect + * that artifact rather than gating on the build exit. Writes the owning + * tmpdir into `td` (caller rm -rf's it) and the unit path into `out`. + * Returns 0 on success, -1 otherwise. */ static int resolveunit(const char *bin, const char *cwd, const char *fixture, int idx, char *td, size_t tdsz, char *out, size_t outsz) @@ -549,18 +549,19 @@ resolveunit(const char *bin, const char *cwd, const char *fixture, snprintf(cmd, sizeof cmd, "cp %s/%s %s", cwd, fixture, tmpsrc); runwait(cmd); snprintf(cmd, sizeof cmd, - "cd %s && timeout 180 %s/ww build %s >/dev/null 2>&1", td, bin, base); + "cd %s && timeout 180 %s/ww build --sep %s >/dev/null 2>&1", + td, bin, base); runwait(cmd); - snprintf(out, outsz, "%s", tmpsrc); - char *dot = strrchr(out, '.'); + char stem[768]; + snprintf(stem, sizeof stem, "%s", tmpsrc); + char *dot = strrchr(stem, '.'); if (dot && strcmp(dot, ".ww") == 0) *dot = '\0'; - size_t n = strlen(out); - snprintf(out + n, outsz - n, ".combined.ww"); + snprintf(out, outsz, "%s.sepwork/__root.unit.ww", stem); return access(out, 0) == 0 ? 0 : -1; } /* Probe 4: ww-side checker (wwdump_ww -r) runs name resolution on each - * selfhost fixture's RESOLVED unit (imports concatenated — see + * selfhost fixture's RESOLVED unit (sep root unit — see * resolveunit) and reports zero unresolved. The raw file would leave * its `import` refs (os/fmt/strconv/ascii members) unresolved, i.e. the * partial unit the asserttyped invariant must never see (harec resolves @@ -578,9 +579,9 @@ probe_resolve(const char *bin) }; int fail = 0; for (int i = 0; fixtures[i]; i++) { - char td[64], combined[1024], a[256], cmd[2048]; + char td[64], unit[1024], a[256], cmd[2048]; if (resolveunit(bin, cwd, fixtures[i], i, td, sizeof td, - combined, sizeof combined) != 0) { + unit, sizeof unit) != 0) { fprintf(stderr, "resolve FAIL: %s — no resolved unit\n", fixtures[i]); fail++; @@ -588,7 +589,7 @@ probe_resolve(const char *bin) } snprintf(a, sizeof a, "/tmp/wwd_r_%d", getpid()); snprintf(cmd, sizeof cmd, "timeout 180 %s/wwdump_ww -r %s > %s 2>/dev/null", - bin, combined, a); + bin, unit, a); int rc = runwait(cmd); if (rc != 0) { fprintf(stderr, "resolve FAIL: %s exited %d (unresolved names)\n", @@ -657,72 +658,21 @@ probe_dump_stable(const char *bin) return fail ? -1 : 0; } -/* Probe 9: full bootstrap fixed-point. ww1 → ww2 → ww3 with - * cmp ww2.s == ww3.s and cmp ww2 == ww3 (byte-identical binaries). - * This is the textbook self-host gate: the compiler must reach a - * fixed point under iterated self-compilation. */ -static int -probe_bootstrap_fixed_point(const char *bin) -{ - char cwd[1024]; - if (getcwd(cwd, sizeof cwd) == NULL) return -1; - char tmpdir[64]; - snprintf(tmpdir, sizeof tmpdir, "/tmp/wwfp_%d", getpid()); - mkdir(tmpdir, 0755); - char ww2s[512], ww2o[512], ww2e[512]; - char ww3s[512], ww3o[512], ww3e[512]; - char rt[1024], cmd[4096]; - snprintf(rt, sizeof rt, "%s/../lib/libwwrt.a", bin); - snprintf(ww2s, sizeof ww2s, "%s/ww2.s", tmpdir); - snprintf(ww2o, sizeof ww2o, "%s/ww2.o", tmpdir); - snprintf(ww2e, sizeof ww2e, "%s/ww2", tmpdir); - snprintf(ww3s, sizeof ww3s, "%s/ww3.s", tmpdir); - snprintf(ww3o, sizeof ww3o, "%s/ww3.o", tmpdir); - snprintf(ww3e, sizeof ww3e, "%s/ww3", tmpdir); - int fail = 0; - /* ww1 -> ww2 */ - snprintf(cmd, sizeof cmd, - "timeout 180 %s/wwdump_ww -c %s/selfhost/cmd/wwdump/main.combined.ww > %s 2>/dev/null", - bin, cwd, ww2s); - if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: ww1 self-compile\n"); fail++; goto cleanup; } - snprintf(cmd, sizeof cmd, "timeout 180 %s/w6a -o %s %s 2>/dev/null", bin, ww2o, ww2s); - if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: w6a ww2.s\n"); fail++; goto cleanup; } - snprintf(cmd, sizeof cmd, "timeout 180 %s/w6l -o %s %s %s 2>/dev/null", bin, ww2e, ww2o, rt); - if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: w6l ww2\n"); fail++; goto cleanup; } - /* ww2 -> ww3 */ - snprintf(cmd, sizeof cmd, - "timeout 180 %s -c %s/selfhost/cmd/wwdump/main.combined.ww > %s 2>/dev/null", - ww2e, cwd, ww3s); - if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: ww2 self-compile\n"); fail++; goto cleanup; } - snprintf(cmd, sizeof cmd, "timeout 180 %s/w6a -o %s %s 2>/dev/null", bin, ww3o, ww3s); - if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: w6a ww3.s\n"); fail++; goto cleanup; } - snprintf(cmd, sizeof cmd, "timeout 180 %s/w6l -o %s %s %s 2>/dev/null", bin, ww3e, ww3o, rt); - if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: w6l ww3\n"); fail++; goto cleanup; } - /* The fixed-point check: ww2.s == ww3.s, ww2 == ww3. */ - snprintf(cmd, sizeof cmd, "cmp -s %s %s", ww2s, ww3s); - if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: ww2.s != ww3.s (no fixed point)\n"); fail++; } - snprintf(cmd, sizeof cmd, "cmp -s %s %s", ww2e, ww3e); - if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: ww2 != ww3 binaries\n"); fail++; } -cleanup: - snprintf(cmd, sizeof cmd, "rm -rf %s", tmpdir); - runwait(cmd); - return fail ? -1 : 0; -} - -/* Probe 7: end-to-end via wwdump_ww. Use `ww build` to produce the - * concatenated source as a side effect, then drive ww-cgen → w6a → - * w6l → run, comparing the binary's exit code to the fixture's - * declared expectation. This is the bootstrap-grade signal: it - * doesn't require ww-cgen output to be byte-identical to C-cgen, - * only to be functionally correct. The byte-match probe above is - * useful while it lasts but layout choices (slot allocation order, - * spill placement) eventually diverge between cgens; correctness is - * the test that scales. */ +/* Probe 7: end-to-end via the ww driver's sep path. `ww_ww build --sep` + * drives the ww-side toolchain (w6c_ww → w6a_ww → w6l_ww) over the + * fixture's package graph — per-package compile, archive, reverse-topo + * link — and we run the result, comparing the exit code to the fixture's + * declared expectation. This is the bootstrap-grade signal: it doesn't + * require byte-identity, only that the ww toolchain links the fixture's + * dep stack (sym/typ/ast via the syntax package, in a SEPARATE `.o`) into + * a functionally correct binary. The single-`.s` link the combined path + * used is gone with combined-mode (the syntax symbols live in their own + * `.o` under --sep, not in the root unit). */ static int probe_ww_links(const char *bin) { const char *fixtures[][2] = { - { "selfhost/test/sym_link.ww", "42" }, /* sym/typ/ast/mem */ + { "selfhost/test/sym_link.ww", "42" }, /* sym/typ/ast via syntax */ { NULL, NULL }, }; char cwd[1024]; @@ -745,41 +695,18 @@ probe_ww_links(const char *bin) char cmd[4096]; snprintf(cmd, sizeof cmd, "cp %s/%s %s", cwd, fix, tmpsrc); runwait(cmd); - /* ww build to get the .combined.ww as a side effect. */ - snprintf(cmd, sizeof cmd, - "cd %s && timeout 180 %s/ww build -I %s/lib/ww -I %s/selfhost/cmd/wcc %s >/dev/null 2>&1", - tmpdir, bin, cwd, cwd, tmpsrc); - if (runwait(cmd) != 0) { - fprintf(stderr, "ww-links FAIL: ww build %s\n", fix); - fail++; - goto cleanup; - } - /* Now compile the combined source via the ww frontend. */ - char combinedp[512], wsp[512], wop[512], wexep[512]; - snprintf(combinedp, sizeof combinedp, "%s.combined.ww", stem); - snprintf(wsp, sizeof wsp, "%s_w.s", stem); - snprintf(wop, sizeof wop, "%s_w.o", stem); + /* Isolated WW_PKGCACHE: the default out/.pkgcache is shared with + * the other phase-2 gates' sep builds (perturb + race). -o + the + * absolute src/-I paths route every side file into tmpdir, so no + * cwd dependency. */ + char wexep[512]; snprintf(wexep, sizeof wexep, "%s_w", stem); snprintf(cmd, sizeof cmd, - "timeout 180 %s/wwdump_ww -c %s > %s 2>/dev/null", bin, combinedp, wsp); + "WW_PKGCACHE='%s.cache' timeout 180 %s/ww_ww build --sep " + "-o %s -I %s/lib/ww -I %s/selfhost/cmd/wcc %s >/dev/null 2>&1", + stem, bin, wexep, cwd, cwd, tmpsrc); if (runwait(cmd) != 0) { - fprintf(stderr, "ww-links FAIL: wwdump_ww -c %s\n", fix); - fail++; - goto cleanup; - } - snprintf(cmd, sizeof cmd, "timeout 180 %s/w6a -o %s %s 2>/dev/null", - bin, wop, wsp); - if (runwait(cmd) != 0) { - fprintf(stderr, "ww-links FAIL: w6a %s\n", fix); - fail++; - goto cleanup; - } - char rt[1024]; - snprintf(rt, sizeof rt, "%s/../lib/libwwrt.a", bin); - snprintf(cmd, sizeof cmd, "timeout 180 %s/w6l -o %s %s %s 2>/dev/null", - bin, wexep, wop, rt); - if (runwait(cmd) != 0) { - fprintf(stderr, "ww-links FAIL: w6l %s\n", fix); + fprintf(stderr, "ww-links FAIL: ww_ww build --sep %s\n", fix); fail++; goto cleanup; } @@ -791,8 +718,6 @@ probe_ww_links(const char *bin) fail++; } cleanup: - /* Sweep tmpdir contents, then remove. ww build also drops a - * C-built binary at — clean it too. */ snprintf(cmd, sizeof cmd, "rm -rf %s", tmpdir); runwait(cmd); } @@ -800,23 +725,20 @@ cleanup: } /* Probe 6: ww-cgen byte-matches C-cgen on each selfhost fixture's - * RESOLVED unit (imports concatenated — see resolveunit). The driver - * always feeds w6c/wwdump a concatenated unit, so the byte-identity - * gate (rule 10) belongs on that shape rather than the raw file; the - * unit also drags in the imported stdlib (os/strconv/ascii), widening - * the convergence set. When this stays empty the cmp ww2 ww3 ceiling - * becomes feasible. + * RESOLVED unit (sep root unit — see resolveunit). The producer feeds + * w6c/wwdump that self-contained unit, so the byte-identity gate (rule + * 10) belongs on that shape rather than the raw file. * - * selfhost/cmd/wcc/err.ww is exercised by probe_resolve but not here: - * its resolved unit pulls in lib/fmt, whose `formattable` match the - * ww-stage checker rejects (check.ww casecovers/casevariantin raise - * ck.errs, so wwdump -c bails before cgen) — a cs≠ww match-exhaustive- - * ness divergence, latent for the bootstrap (the compiler's own - * main.combined.ww imports no fmt) and tracked separately. */ + * err.ww is included now (it was excluded under combined-mode, where its + * unit inlined lib/fmt's BODY and the ww checker rejected fmt's + * `formattable` match-exhaustiveness): the sep unit inlines only fmt's + * `.wwi` INTERFACE, so the fmt body never reaches the checker and err's + * root cgen converges cs==ww. */ static int probe_cgen_match(const char *bin) { const char *files[] = { + "selfhost/cmd/wcc/err.ww", "lib/ww/syntax/tok.ww", "selfhost/test/smoke.ww", NULL, @@ -825,9 +747,9 @@ probe_cgen_match(const char *bin) if (getcwd(cwd, sizeof cwd) == NULL) return -1; int fail = 0; for (int i = 0; files[i]; i++) { - char td[64], combined[1024], a[256], b[256], cmd[2048]; + char td[64], unit[1024], a[256], b[256], cmd[2048]; if (resolveunit(bin, cwd, files[i], i, td, sizeof td, - combined, sizeof combined) != 0) { + unit, sizeof unit) != 0) { fprintf(stderr, "cgen-match FAIL: %s — no resolved unit\n", files[i]); fail++; @@ -836,10 +758,10 @@ probe_cgen_match(const char *bin) snprintf(a, sizeof a, "/tmp/wwd_cm_%d_c", getpid()); snprintf(b, sizeof b, "/tmp/wwd_cm_%d_w", getpid()); snprintf(cmd, sizeof cmd, "timeout 180 %s/w6c %s > %s 2>/dev/null", - bin, combined, a); + bin, unit, a); runwait(cmd); snprintf(cmd, sizeof cmd, "timeout 180 %s/wwdump_ww -c %s > %s 2>/dev/null", - bin, combined, b); + bin, unit, b); runwait(cmd); char *bc = NULL, *bw = NULL; size_t nc = 0, nw = 0; @@ -876,19 +798,26 @@ main(void) if (probe_ww_compile(bin) != 0) fail++; if (probe_cgen_match(bin) != 0) fail++; if (probe_ww_links(bin) != 0) fail++; - if (probe_bootstrap_fixed_point(bin) != 0) fail++; if (fail) { fprintf(stderr, "selfhost: %d probe(s) failed\n", fail); return 1; } + /* The ww1->ww2->ww3 binary fixed point is no longer reproducible here: + * it self-compiled wwdump as a monolith from main.combined.ww, a model + * combined-mode provided and --sep retires (the sep root unit holds only + * the root body + dep INTERFACE stubs, not a linkable whole program). The + * two axes it covered now live elsewhere: the self-application fixed point + * (iterated self-compile converges, ww2==ww3==ww4) is `make bootstrap`'s + * sep-path gate (migrated E2-C1); the orthogonal wwstage==cstage byte + * identity is 995_self_rebuild, which drives ww_ww --sep over all five + * tools (wwdump included) and byte-compares against the cstage binaries. */ printf("selfhost: codegen ok; smoke=42; wwdump stable; " "ww lexer matches C on 8 fixtures (-t); " "ww parser matches C on 32 fixtures (-a); " - "ww checker resolves 3 fixtures' import-concatenated units (-r); " + "ww checker resolves 3 fixtures' sep root units (-r); " "ww cgen compiles + runs 13 ww programs (incl. compound -= regression); " - "ww cgen byte-matches C on 2 resolved units (tok/smoke); " - "ww cgen builds runnable binaries from sym/typ/ast/mem stack; " - "ww1 -> ww2 -> ww3 fixed-point reached: ww2.s == ww3.s, ww2 == ww3 byte-identical\n"); + "ww cgen byte-matches C on 3 sep root units (err/tok/smoke); " + "ww toolchain sep-builds + runs the syntax dep stack (sym_link=42)\n"); return 0; } diff --git a/test/wcc/994_w6c_ww.c b/test/wcc/994_w6c_ww.c index bda19fc7..732bd5e5 100644 --- a/test/wcc/994_w6c_ww.c +++ b/test/wcc/994_w6c_ww.c @@ -120,41 +120,6 @@ files_eq(const char *a, const char *b) return eq ? 0 : 1; } -/* Tier-C oracle helper (rob-c6-spec §2 / amendment-B): a sep-built w6c at - * `sepw6c` must EMIT byte-identical asm to the combined-built `w6c_ww` on - * `target`. (We assert OUTPUT equivalence, never `cmp` the tool binaries — - * sep vs combined differ by a constant link-layout delta.) Returns 0 on - * byte-identical .s, non-zero otherwise. */ -static int -emit_eq(const char *sepw6c, const char *w6c_ww, const char *target, - const char *label) -{ - char a[64], b[64], cmd[4096]; - snprintf(a, sizeof a, "/tmp/wwc6tc_%d_sep.s", getpid()); - snprintf(b, sizeof b, "/tmp/wwc6tc_%d_comb.s", getpid()); - snprintf(cmd, sizeof cmd, "timeout 240 %s -o %s %s 2>/dev/null", - sepw6c, a, target); - if (runwait(cmd) != 0) { - fprintf(stderr, "Tier-C FAIL: sep-w6c emit errored on %s\n", label); - unlink(a); - return 1; - } - snprintf(cmd, sizeof cmd, "timeout 240 %s -o %s %s 2>/dev/null", - w6c_ww, b, target); - if (runwait(cmd) != 0) { - fprintf(stderr, "Tier-C FAIL: combined-w6c_ww emit errored on %s\n", - label); - unlink(a); unlink(b); - return 1; - } - int rc = files_eq(a, b); - if (rc != 0) - fprintf(stderr, "Tier-C FAIL: %s — sep-out != combined-out " - "(M4 output-equivalence broken)\n", label); - unlink(a); unlink(b); - return rc == 0 ? 0 : 1; -} - /* cs==ww over a sep-build's per-package artifacts: every .s/.o/.wwi the * cstage driver produced in `csdir` must be byte-identical to the wwstage * driver's same-named file in `wwdir` (rule 10; the .wwi interface files @@ -309,17 +274,6 @@ main(void) { NULL, NULL }, }; - /* Source-tree corpus: the same .combined.ww files the bootstrap - * fixed point chews on. Confirms w6c_ww handles realistic inputs, - * not just hand-tailored ones. */ - const char *combined_rel[] = { - "selfhost/cmd/wwdump/main.combined.ww", - "selfhost/cmd/w6a/main.combined.ww", - "selfhost/cmd/w6l/main.combined.ww", - "selfhost/cmd/ww/main.combined.ww", - NULL, - }; - int fail = 0, n = 0; for (int i = 0; progs[i].label; i++) { @@ -330,12 +284,6 @@ main(void) unlink(src); n++; } - for (int i = 0; combined_rel[i]; i++) { - char p[2048]; - snprintf(p, sizeof p, "%s/%s", cwd, combined_rel[i]); - if (diff_one(bin, combined_rel[i], p) != 0) fail++; - n++; - } /* #50: the check pass is wired into both wwdump_ww -c and * w6c_ww in front of cgen. Pre-#50, a hard type error parsed @@ -376,22 +324,19 @@ main(void) n++; } - /* ---- Tier-C capstone (#46 c6, rob-c6-spec §2 / amendment-B) ---------- - * Fold the dual-path soak into this bootstrap oracle: a w6c built by - * SEPARATE compilation must EMIT byte-identical .s to the combined-built - * w6c_ww on every real bootstrap input, and both driver stages must - * sep-produce byte-identical per-package .s/.o/.wwi (cs==ww on the real - * tool's sep artifacts). This is the load-bearing M4 proof — the - * combined-out==sep-out leg the bootstrap fixed point alone cannot reach. - * We assert OBSERVABLE OUTPUT, never `cmp` the tool binaries (sep vs - * combined differ by a constant link-layout delta). COLD (pid-keyed - * scratch, wiped); heavy (≈ one bootstrap leg) → this gate is phase-2. */ + /* ---- Tier-C capstone (#46 c6, rob-c6-spec §2 / amendment-B; M4 #89) --- + * The load-bearing M4 oracle: build w6c by SEPARATE compilation under + * BOTH driver stages and prove they sep-produce byte-identical per-package + * .s/.o/.wwi (cs==ww on the real tool's sep artifacts, rule 10). The + * combined corpus + the sep-out==combined-out leg are gone — combined-mode + * is being retired (E3 flip), so combined.ww is no longer fed as compiler + * INPUT; the per-pkg cs==ww comparison is the surviving live oracle. COLD + * (pid-keyed scratch, wiped); heavy (≈ one bootstrap leg) → phase-2. */ { char inc[4096], cmd[16384]; snprintf(inc, sizeof inc, "-I %s/lib -I %s/lib/ww -I %s/selfhost/cmd/wcc", cwd, cwd, cwd); - char w6c_ww[2048], root[2048]; - snprintf(w6c_ww, sizeof w6c_ww, "%s/w6c_ww", bin); + char root[2048]; snprintf(root, sizeof root, "%s/selfhost/cmd/w6c/main.ww", cwd); struct { const char *drv, *tag; char prog[2048]; int ok; } @@ -415,29 +360,6 @@ main(void) n++; } - /* OUTPUT equivalence on every real bootstrap input: each built - * sep-w6c vs the combined w6c_ww (the M4 combined-out==sep-out bar; - * cs==ww follows since both sep stages match the same reference). */ - const char *targ[] = { - "selfhost/cmd/w6c/main.combined.ww", - "selfhost/cmd/wwdump/main.combined.ww", - "selfhost/cmd/w6a/main.combined.ww", - "selfhost/cmd/w6l/main.combined.ww", - "selfhost/cmd/ww/main.combined.ww", - NULL, - }; - for (int s = 0; s < 2; s++) { - if (!stg[s].ok) continue; - for (int i = 0; targ[i]; i++) { - char t[2048], label[256]; - snprintf(t, sizeof t, "%s/%s", cwd, targ[i]); - snprintf(label, sizeof label, "sep-%s emit %s", - stg[s].tag, targ[i]); - if (emit_eq(stg[s].prog, w6c_ww, t, label) != 0) fail++; - n++; - } - } - /* cs==ww on the real tool's sep .s/.o/.wwi (rule 10). */ if (stg[0].ok && stg[1].ok) { char csdir[2176], wwdir[2176]; @@ -458,9 +380,8 @@ main(void) fprintf(stderr, "w6c_ww: %d/%d diff(s) failed\n", fail, n); return 1; } - printf("w6c_ww: byte-identical to wwdump_ww -c on %d corpus inputs " - "(in-source + selfhost combined.ww) + Tier-C: sep-built w6c emits " - "== combined w6c_ww on all bootstrap inputs, cs==ww sep .s/.o/.wwi\n", + printf("w6c_ww: byte-identical to wwdump_ww -c on %d in-source corpus " + "inputs + Tier-C: cs==ww sep .s/.o/.wwi on the real w6c build\n", n); return 0; }