From bbd2ad390a07cfa4095035ce72030a31312ad9d0 Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Thu, 18 Jun 2026 16:44:41 +0900 Subject: [PATCH] test: retarget Pattern-A combined-feed gates to sep .sepwork layout (M4 E3, #94) 94a of the C-mig2 split (rob rule-11): 13 Pattern-A gates that fed a .combined.ww to w6c/w6c_ww now drive two --sep builds (ww / ww_ww) and byte-diff the concatenated per-package .sepwork/*.s, mirroring #93's convention. Lands pre-flip while combined.ww still exists as the reversible safety net. Test-only; all 5 binary pins HOLD. 989_enumcap_run deferred to 94b (its decisive assertion is a combined.ww content diff, not a .s diff). --- Makefile | 18 ++-- test/wcc/784_xmod_alias_struct_collide_run.c | 52 ++++++------ test/wcc/787_xmod_variant_match.c | 89 +++++++++----------- test/wcc/792_spread_variant_match.c | 50 +++++------ test/wcc/794_xmod_ident_prefer.c | 52 +++++------- test/wcc/815_fmt_int_run.c | 58 +++++++------ test/wcc/848_xmod_qualstructlit_run.c | 51 +++++------ test/wcc/911_attest_record.c | 50 ++++++----- test/wcc/940_global_sret_run.c | 85 ++++++++++--------- test/wcc/949_xmod_fnptr_const_run.c | 87 ++++++++----------- test/wcc/951_defdim_struct_run.c | 83 +++++++++--------- test/wcc/989_callarg_typecheck.c | 58 ++++++------- test/wcc/989_m1mangle_run.c | 13 ++- test/wcc/989_m2wwi_run.c | 22 +++-- 14 files changed, 377 insertions(+), 391 deletions(-) diff --git a/Makefile b/Makefile index bb2f93fb..417712ef 100644 --- a/Makefile +++ b/Makefile @@ -1830,7 +1830,7 @@ $(BIN)/test_type_value_shadow_run: test/wcc/788_type_value_shadow_run.c \ # fixtures in a private mktemp dir — not a selfhost-driver test. $(BIN)/test_xmod_alias_struct_collide_run: test/wcc/784_xmod_alias_struct_collide_run.c \ $(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \ - $(BIN)/w6c_ww \ + $(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \ $(LIB)/libwwrt.a | $(BIN) $(CC) $(CFLAGS) -o $@ $< @@ -1841,7 +1841,7 @@ $(BIN)/test_xmod_alias_struct_collide_run: test/wcc/784_xmod_alias_struct_collid # Builds its own 2-module fixtures in a private mktemp dir. $(BIN)/test_xmod_variant_match: test/wcc/787_xmod_variant_match.c \ $(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \ - $(BIN)/w6c_ww \ + $(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \ $(LIB)/libwwrt.a | $(BIN) $(CC) $(CFLAGS) -o $@ $< @@ -1854,7 +1854,8 @@ $(BIN)/test_xmod_variant_match: test/wcc/787_xmod_variant_match.c \ # Builds its own 2-module fixtures in a private mktemp dir. $(BIN)/test_xmod_qualstructlit_run: test/wcc/848_xmod_qualstructlit_run.c \ $(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \ - $(BIN)/w6c_ww $(BIN)/wwdump $(BIN)/wwdump_ww \ + $(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \ + $(BIN)/wwdump $(BIN)/wwdump_ww \ $(LIB)/libwwrt.a | $(BIN) $(CC) $(CFLAGS) -o $@ $< @@ -1868,7 +1869,7 @@ $(BIN)/test_xmod_qualstructlit_run: test/wcc/848_xmod_qualstructlit_run.c \ # discriminator. Self-contained single-file probe. $(BIN)/test_spread_variant_match: test/wcc/792_spread_variant_match.c \ $(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \ - $(BIN)/w6c_ww \ + $(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \ $(LIB)/libwwrt.a | $(BIN) $(CC) $(CFLAGS) -o $@ $< @@ -1885,7 +1886,7 @@ $(BIN)/test_widen_pad_zero_run: test/wcc/793_widen_pad_zero_run.c \ # 2-module fixtures in a private mktemp dir. $(BIN)/test_xmod_ident_prefer: test/wcc/794_xmod_ident_prefer.c \ $(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \ - $(BIN)/w6c_ww \ + $(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \ $(LIB)/libwwrt.a | $(BIN) $(CC) $(CFLAGS) -o $@ $< @@ -2950,7 +2951,9 @@ $(BIN)/test_dyn_ww: test/wcc/996_dyn_ww.c $(BIN)/ww $(BIN)/w6l $(BIN)/w6l_ww \ $(CC) $(CFLAGS) -o $@ $< $(BIN)/test_attest_record: test/wcc/911_attest_record.c $(BIN)/ww $(BIN)/w6c \ - $(BIN)/w6c_ww $(BIN)/w6a $(BIN)/w6l $(LIB)/libwwrt.a | $(BIN) + $(BIN)/w6a $(BIN)/w6l \ + $(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \ + $(LIB)/libwwrt.a | $(BIN) $(CC) $(CFLAGS) -o $@ $< # C2b — #6 @test drop/keep/link via direct w6c/w6c_ww on import-free fixtures @@ -3351,7 +3354,8 @@ $(BIN)/test_structlit_arrfield_run: test/wcc/949_structlit_arrfield_run.c \ $(CC) $(CFLAGS) -o $@ $< $(BIN)/test_defdim_struct_run: test/wcc/951_defdim_struct_run.c \ - $(BIN)/ww $(BIN)/w6c $(BIN)/w6c_ww $(BIN)/w6a $(BIN)/w6l \ + $(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \ + $(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \ $(LIB)/libwwrt.a | $(BIN) $(CC) $(CFLAGS) -o $@ $< diff --git a/test/wcc/784_xmod_alias_struct_collide_run.c b/test/wcc/784_xmod_alias_struct_collide_run.c index b385a759..5e7307c6 100644 --- a/test/wcc/784_xmod_alias_struct_collide_run.c +++ b/test/wcc/784_xmod_alias_struct_collide_run.c @@ -239,9 +239,10 @@ static const struct scenario scenarios[] = { }; static int -run_scenario(const char *bin, const char *w6c, const char *w6c_ww, +run_scenario(const char *bin, const char *cdrv, const char *wdrv, const struct scenario *sc) { + (void)bin; /* Private fixture dir — #215: srcd is this dir (not shared /tmp), * so the driver's srcd-first import search can't pick up a * polluting same-name file. mkdtemp gives a unique path. */ @@ -263,9 +264,11 @@ run_scenario(const char *bin, const char *w6c, const char *w6c_ww, fclose(f); } - /* cstage driver build + run: pins runtime. */ - snprintf(cmd, sizeof cmd, "cd %s && %s/ww build -I %s %s/main.ww", - dir, bin, dir, dir); + /* #94 sep layout: cstage --sep build + run pins runtime; pin + * WW_PKGCACHE under the scratch dir so out/.pkgcache is untouched. */ + snprintf(cmd, sizeof cmd, + "cd %s && WW_PKGCACHE=%s/pkgc_c %s build --sep -I %s -o %s/main %s/main.ww", + dir, dir, cdrv, dir, dir, dir); if (runwait(cmd) != 0) { fprintf(stderr, "784[%s]: cstage build failed\n", sc->label); rc = -1; goto done; @@ -278,23 +281,24 @@ run_scenario(const char *bin, const char *w6c, const char *w6c_ww, rc = -1; } - /* Byte-id net (the #223 discriminator): raw w6c vs w6c_ww on the - * driver-produced combined.ww. Pre-fix the dispatcher diverges. */ - char cs_s[1024], ws_s[1024], comb[1024]; - snprintf(comb, sizeof comb, "%s/main.combined.ww", dir); - snprintf(cs_s, sizeof cs_s, "%s/cs.s", dir); - snprintf(ws_s, sizeof ws_s, "%s/ww.s", dir); - snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, cs_s, comb); + /* Byte-id net (the #223 discriminator): the wwstage driver's --sep + * build emits per-package w6c_ww asm; pre-fix the dispatcher diverges. + * The root + each imported pkg compile to separate .sepwork/.s; + * concat (sorted glob, identical set both stages) for the compare. */ + char cs_s[1024], ws_s[1024]; + snprintf(cmd, sizeof cmd, + "cd %s && WW_PKGCACHE=%s/pkgc_w %s build --sep -I %s -o %s/mainww %s/main.ww", + dir, dir, wdrv, dir, dir, dir); if (runwait(cmd) != 0) { - fprintf(stderr, "784[%s]: w6c on combined failed\n", sc->label); - rc = -1; goto done; - } - snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c_ww, ws_s, comb); - if (runwait(cmd) != 0) { - fprintf(stderr, "784[%s]: w6c_ww on combined failed\n", - sc->label); + fprintf(stderr, "784[%s]: ww_ww build failed\n", sc->label); rc = -1; goto done; } + snprintf(cs_s, sizeof cs_s, "%s/all_cs.s", dir); + snprintf(ws_s, sizeof ws_s, "%s/all_ww.s", dir); + snprintf(cmd, sizeof cmd, "cat %s/main.sepwork/*.s > %s 2>/dev/null", + dir, cs_s); if (system(cmd)) {} + snprintf(cmd, sizeof cmd, "cat %s/mainww.sepwork/*.s > %s 2>/dev/null", + dir, ws_s); if (system(cmd)) {} if (slurp_eq(cs_s, ws_s) != 0) { fprintf(stderr, "784[%s]: cs.s/ww.s DIFFER (rule-10 byte-id " "violation — #223 regression)\n", sc->label); @@ -321,11 +325,11 @@ main(void) bin = absbin; } - char w6c[2100], w6c_ww[2100]; - snprintf(w6c, sizeof w6c, "%s/w6c", bin); - snprintf(w6c_ww, sizeof w6c_ww, "%s/w6c_ww", bin); - if (access(w6c_ww, X_OK) != 0) { - fprintf(stderr, "784: w6c_ww missing — cannot run the cs==ww " + char cdrv[2100], wdrv[2100]; + snprintf(cdrv, sizeof cdrv, "%s/ww", bin); + snprintf(wdrv, sizeof wdrv, "%s/ww_ww", bin); + if (access(wdrv, X_OK) != 0) { + fprintf(stderr, "784: ww_ww missing — cannot run the cs==ww " "byte-id gate (the whole point of this test)\n"); return 1; } @@ -333,7 +337,7 @@ main(void) int n = (int)(sizeof scenarios / sizeof scenarios[0]); int fail = 0; for (int i = 0; i < n; i++) { - if (run_scenario(bin, w6c, w6c_ww, &scenarios[i]) != 0) + if (run_scenario(bin, cdrv, wdrv, &scenarios[i]) != 0) fail++; } diff --git a/test/wcc/787_xmod_variant_match.c b/test/wcc/787_xmod_variant_match.c index 0fad7751..5fa65a5a 100644 --- a/test/wcc/787_xmod_variant_match.c +++ b/test/wcc/787_xmod_variant_match.c @@ -223,9 +223,10 @@ static const struct scenario scenarios[] = { }; static int -run_scenario(const char *bin, const char *w6c, const char *w6c_ww, +run_scenario(const char *bin, const char *cdrv, const char *wdrv, const struct scenario *sc) { + (void)bin; char dir[] = "/tmp/ww787_XXXXXX"; if (mkdtemp(dir) == NULL) { fprintf(stderr, "787[%s]: mkdtemp failed\n", sc->label); @@ -244,48 +245,37 @@ run_scenario(const char *bin, const char *w6c, const char *w6c_ww, fclose(f); } - char comb[1024]; - snprintf(comb, sizeof comb, "%s/main.combined.ww", dir); - if (sc->expect_reject) { - /* The driver build MUST fail (cstage's checker rejects the - * foreign-qualifier variant), but expand() still writes the - * combined unit before the checker runs — so re-check it with - * BOTH backends and require BOTH to reject. w6c_ww accepting + /* #94 sep layout: there is no combined unit to re-check. The + * checker reject now fires inside each driver's --sep w6c pass, + * so BOTH driver builds MUST fail. w6c_ww (via ww_ww) accepting * here is the #13 false-ACCEPT regression. */ - char xs[1024]; - snprintf(xs, sizeof xs, "%s/x.s", dir); snprintf(cmd, sizeof cmd, - "cd %s && %s/ww build -I %s %s/main.ww >/dev/null 2>&1", - dir, bin, dir, dir); + "cd %s && WW_PKGCACHE=%s/pkgc_c %s build --sep -I %s " + "-o %s/main %s/main.ww >/dev/null 2>&1", + dir, dir, cdrv, dir, dir, dir); if (runwait(cmd) == 0) { fprintf(stderr, "787[%s]: cstage build SUCCEEDED, " "expected reject\n", sc->label); rc = -1; goto done; } - if (access(comb, 0) != 0) { - fprintf(stderr, "787[%s]: no combined.ww to re-check\n", - sc->label); - rc = -1; goto done; - } - snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, xs, comb); + snprintf(cmd, sizeof cmd, + "cd %s && WW_PKGCACHE=%s/pkgc_w %s build --sep -I %s " + "-o %s/mainww %s/main.ww >/dev/null 2>&1", + dir, dir, wdrv, dir, dir, dir); if (runwait(cmd) == 0) { - fprintf(stderr, "787[%s]: w6c ACCEPTED foreign variant, " - "expected reject\n", sc->label); - rc = -1; goto done; - } - snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c_ww, xs, comb); - if (runwait(cmd) == 0) { - fprintf(stderr, "787[%s]: w6c_ww ACCEPTED foreign variant " + fprintf(stderr, "787[%s]: ww_ww ACCEPTED foreign variant " "(#13 false-accept), expected reject\n", sc->label); rc = -1; goto done; } goto done; } - /* cstage driver build + run: pins runtime routing. */ - snprintf(cmd, sizeof cmd, "cd %s && %s/ww build -I %s %s/main.ww", - dir, bin, dir, dir); + /* cstage driver --sep build + run: pins runtime routing. Pin + * WW_PKGCACHE under the scratch dir so out/.pkgcache is untouched. */ + snprintf(cmd, sizeof cmd, + "cd %s && WW_PKGCACHE=%s/pkgc_c %s build --sep -I %s -o %s/main %s/main.ww", + dir, dir, cdrv, dir, dir, dir); if (runwait(cmd) != 0) { fprintf(stderr, "787[%s]: cstage build failed\n", sc->label); rc = -1; goto done; @@ -298,24 +288,27 @@ run_scenario(const char *bin, const char *w6c, const char *w6c_ww, rc = -1; } - /* The #13 discriminator: raw w6c_ww on the driver-produced - * combined.ww. Pre-fix the wwstage checker REJECTED the - * cross-module variant arms (non-zero exit here). Post-fix it - * accepts AND is byte-id with cstage's w6c. */ - char cs_s[1024], ws_s[1024]; - snprintf(cs_s, sizeof cs_s, "%s/cs.s", dir); - snprintf(ws_s, sizeof ws_s, "%s/ww.s", dir); - snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, cs_s, comb); + /* The #13 discriminator: the wwstage driver's --sep build runs the + * wwstage checker over the same units. Pre-fix it REJECTED the + * cross-module variant arms (build fails); post-fix it accepts AND + * its per-package w6c_ww asm is byte-id with cstage's. The root + + * each imported pkg compile to separate .sepwork/.s; + * concat (sorted glob, identical set both stages) for the compare. */ + snprintf(cmd, sizeof cmd, + "cd %s && WW_PKGCACHE=%s/pkgc_w %s build --sep -I %s -o %s/mainww %s/main.ww", + dir, dir, wdrv, dir, dir, dir); if (runwait(cmd) != 0) { - fprintf(stderr, "787[%s]: w6c on combined failed\n", sc->label); - rc = -1; goto done; - } - snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c_ww, ws_s, comb); - if (runwait(cmd) != 0) { - fprintf(stderr, "787[%s]: w6c_ww on combined failed " + fprintf(stderr, "787[%s]: ww_ww build failed " "(#13 cross-module variant reject?)\n", sc->label); rc = -1; goto done; } + char cs_s[1024], ws_s[1024]; + snprintf(cs_s, sizeof cs_s, "%s/all_cs.s", dir); + snprintf(ws_s, sizeof ws_s, "%s/all_ww.s", dir); + snprintf(cmd, sizeof cmd, "cat %s/main.sepwork/*.s > %s 2>/dev/null", + dir, cs_s); if (system(cmd)) {} + snprintf(cmd, sizeof cmd, "cat %s/mainww.sepwork/*.s > %s 2>/dev/null", + dir, ws_s); if (system(cmd)) {} if (slurp_eq(cs_s, ws_s) != 0) { fprintf(stderr, "787[%s]: cs.s/ww.s DIFFER (rule-10 byte-id " "violation)\n", sc->label); @@ -341,11 +334,11 @@ main(void) bin = absbin; } - char w6c[2100], w6c_ww[2100]; - snprintf(w6c, sizeof w6c, "%s/w6c", bin); - snprintf(w6c_ww, sizeof w6c_ww, "%s/w6c_ww", bin); - if (access(w6c_ww, X_OK) != 0) { - fprintf(stderr, "787: w6c_ww missing — cannot run the cs==ww " + char cdrv[2100], wdrv[2100]; + snprintf(cdrv, sizeof cdrv, "%s/ww", bin); + snprintf(wdrv, sizeof wdrv, "%s/ww_ww", bin); + if (access(wdrv, X_OK) != 0) { + fprintf(stderr, "787: ww_ww missing — cannot run the cs==ww " "byte-id gate (the whole point of this test)\n"); return 1; } @@ -353,7 +346,7 @@ main(void) int n = (int)(sizeof scenarios / sizeof scenarios[0]); int fail = 0; for (int i = 0; i < n; i++) { - if (run_scenario(bin, w6c, w6c_ww, &scenarios[i]) != 0) + if (run_scenario(bin, cdrv, wdrv, &scenarios[i]) != 0) fail++; } diff --git a/test/wcc/792_spread_variant_match.c b/test/wcc/792_spread_variant_match.c index 37116121..4ec163a9 100644 --- a/test/wcc/792_spread_variant_match.c +++ b/test/wcc/792_spread_variant_match.c @@ -96,11 +96,11 @@ main(void) bin = absbin; } - char w6c[2100], w6c_ww[2100]; - snprintf(w6c, sizeof w6c, "%s/w6c", bin); - snprintf(w6c_ww, sizeof w6c_ww, "%s/w6c_ww", bin); - if (access(w6c_ww, X_OK) != 0) { - fprintf(stderr, "792: w6c_ww missing — cannot run the cs==ww " + char cdrv[2100], wdrv[2100]; + snprintf(cdrv, sizeof cdrv, "%s/ww", bin); + snprintf(wdrv, sizeof wdrv, "%s/ww_ww", bin); + if (access(wdrv, X_OK) != 0) { + fprintf(stderr, "792: ww_ww missing — cannot run the cs==ww " "byte-id gate (the whole point of this test)\n"); return 1; } @@ -108,7 +108,7 @@ main(void) char dir[] = "/tmp/ww792_XXXXXX"; if (mkdtemp(dir) == NULL) { fprintf(stderr, "792: mkdtemp\n"); return 1; } - char path[1024], cmd[4096], comb[1024], cs_s[1024], ws_s[1024]; + char path[1024], cmd[4096], cs_s[1024], ws_s[1024]; int rc = 0; snprintf(path, sizeof path, "%s/main.ww", dir); @@ -117,33 +117,29 @@ main(void) fputs(SRC, f); fclose(f); - snprintf(comb, sizeof comb, "%s/main.combined.ww", dir); + /* #94: sep layout. The cstage driver's --sep build emits the root + * unit's asm to .sepwork/__root.s via its internal w6c; pin + * WW_PKGCACHE under the scratch dir so out/.pkgcache is untouched. */ + snprintf(cs_s, sizeof cs_s, "%s/main.sepwork/__root.s", dir); + snprintf(ws_s, sizeof ws_s, "%s/mainww.sepwork/__root.s", dir); - /* cstage driver build: produces the combined.ww + must accept. */ - snprintf(cmd, sizeof cmd, "cd %s && %s/ww build -I %s %s/main.ww", - dir, bin, dir, dir); + snprintf(cmd, sizeof cmd, + "cd %s && WW_PKGCACHE=%s/pkgc_c %s build --sep -I %s -o %s/main %s/main.ww", + dir, dir, cdrv, dir, dir, dir); if (runwait(cmd) != 0) { - fprintf(stderr, "792: cstage build failed\n"); - rc = 1; goto done; - } - if (access(comb, 0) != 0) { - fprintf(stderr, "792: no combined.ww produced\n"); + fprintf(stderr, "792: cstage sep build failed\n"); rc = 1; goto done; } - /* The #209 discriminator: raw w6c_ww on the combined. Pre-fix the - * wwstage checker REJECTED the spread-union match arms (non-zero - * exit). Post-fix it accepts AND is byte-id with cstage's w6c. */ - snprintf(cs_s, sizeof cs_s, "%s/cs.s", dir); - snprintf(ws_s, sizeof ws_s, "%s/ww.s", dir); - snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, cs_s, comb); + /* The #209 discriminator: the wwstage driver's --sep build runs the + * wwstage checker over the same root unit. Pre-fix it REJECTED the + * spread-union match arms (build fails); post-fix it accepts AND its + * w6c_ww-emitted __root.s is byte-id with the cstage __root.s. */ + snprintf(cmd, sizeof cmd, + "cd %s && WW_PKGCACHE=%s/pkgc_w %s build --sep -I %s -o %s/mainww %s/main.ww", + dir, dir, wdrv, dir, dir, dir); if (runwait(cmd) != 0) { - fprintf(stderr, "792: w6c on combined failed\n"); - rc = 1; goto done; - } - snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c_ww, ws_s, comb); - if (runwait(cmd) != 0) { - fprintf(stderr, "792: w6c_ww on combined failed " + fprintf(stderr, "792: wwstage sep build failed " "(#209 spread-union match reject?)\n"); rc = 1; goto done; } diff --git a/test/wcc/794_xmod_ident_prefer.c b/test/wcc/794_xmod_ident_prefer.c index 682147e3..5042b26d 100644 --- a/test/wcc/794_xmod_ident_prefer.c +++ b/test/wcc/794_xmod_ident_prefer.c @@ -96,11 +96,11 @@ main(void) bin = absbin; } - char w6c[2100], w6c_ww[2100]; - snprintf(w6c, sizeof w6c, "%s/w6c", bin); - snprintf(w6c_ww, sizeof w6c_ww, "%s/w6c_ww", bin); - if (access(w6c_ww, X_OK) != 0) { - fprintf(stderr, "794: w6c_ww missing — cannot run the wwstage " + char cdrv[2100], wdrv[2100]; + snprintf(cdrv, sizeof cdrv, "%s/ww", bin); + snprintf(wdrv, sizeof wdrv, "%s/ww_ww", bin); + if (access(wdrv, X_OK) != 0) { + fprintf(stderr, "794: ww_ww missing — cannot run the wwstage " "accept gate (the whole point of this test)\n"); return 1; } @@ -123,9 +123,14 @@ main(void) fclose(f); } - /* cstage driver build (prefer is correct) emits the combined unit. */ - snprintf(cmd, sizeof cmd, "cd %s && %s/ww build -I %s %s/main.ww", - dir, bin, dir, dir); + /* #94 sep layout: cstage's --sep build (prefer is correct) compiles + * the units and links the binary; pin WW_PKGCACHE under the scratch + * dir so out/.pkgcache is untouched. NO cs==ww byte-id here — the #55 + * checker fix has an open cgen-side bare-leaf sibling that diverges the + * asm independently; the sound discriminator is the wwstage ACCEPT. */ + snprintf(cmd, sizeof cmd, + "cd %s && WW_PKGCACHE=%s/pkgc_c %s build --sep -I %s -o %s/main %s/main.ww", + dir, dir, cdrv, dir, dir, dir); if (runwait(cmd) != 0) { fprintf(stderr, "794: cstage build failed\n"); rc = 1; goto done; @@ -138,29 +143,16 @@ main(void) rc = 1; goto done; } - char comb[1024]; - snprintf(comb, sizeof comb, "%s/main.combined.ww", dir); - if (access(comb, 0) != 0) { - fprintf(stderr, "794: no combined.ww emitted\n"); - rc = 1; goto done; - } - - /* Sanity: cstage's own backend re-accepts its combined. */ - char cs_s[1024], ws_s[1024]; - snprintf(cs_s, sizeof cs_s, "%s/cs.s", dir); - snprintf(ws_s, sizeof ws_s, "%s/ww.s", dir); - snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, cs_s, comb); + /* The #55 discriminator: the wwstage driver's --sep build runs the + * wwstage checker over the same units and must ACCEPT. PRE-fix it + * rejected (bare `v` -> main.v: i64 -> return mismatch); POST-fix it + * prefers curmod=aa -> aa.v: i32 and accepts. */ + snprintf(cmd, sizeof cmd, + "cd %s && WW_PKGCACHE=%s/pkgc_w %s build --sep -I %s -o %s/mainww %s/main.ww " + ">/dev/null 2>&1", + dir, dir, wdrv, dir, dir, dir); if (runwait(cmd) != 0) { - fprintf(stderr, "794: w6c on combined failed\n"); - rc = 1; goto done; - } - - /* The #55 discriminator: w6c_ww must ACCEPT the combined unit. - * PRE-fix it rejected (bare `v` -> main.v: i64 -> return mismatch); - * POST-fix it prefers curmod=aa -> aa.v: i32 and accepts. */ - snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c_ww, ws_s, comb); - if (runwait(cmd) != 0) { - fprintf(stderr, "794: w6c_ww REJECTED the combined (#55: bare " + fprintf(stderr, "794: ww_ww REJECTED the units (#55: bare " "value-ident resolved the wrong module's same-leaf symbol)\n"); rc = 1; goto done; } diff --git a/test/wcc/815_fmt_int_run.c b/test/wcc/815_fmt_int_run.c index dcba77be..d1c97c84 100644 --- a/test/wcc/815_fmt_int_run.c +++ b/test/wcc/815_fmt_int_run.c @@ -268,51 +268,55 @@ run_row(const char *driver, const char *cwd, const struct row *r, int seq) return rc; } -/* asm_byte_identical — build combined.ww via the cstage driver (needs - * the -I lib fmt import resolution that raw w6c can't do), then compile - * that combined.ww with both w6c and w6c_ww and diff the asm. Proves no - * cs!=ww tag/render divergence on the widened union. */ +/* asm_byte_identical — #94 sep layout: the cstage driver's --sep build + * (which needs -I lib for fmt import resolution that raw w6c can't do) + * emits per-package w6c asm to _c.sepwork/, and the wwstage driver's + * --sep build emits per-package w6c_ww asm to _w.sepwork/. Concat + * (sorted glob, identical package set) and diff — proves no cs!=ww + * tag/render divergence on the widened union. */ static int -asm_byte_identical(const char *bin, const char *cdrv, const char *cwd, +asm_byte_identical(const char *cdrv, const char *wdrv, const char *cwd, const struct row *r, int seq) { - char tmpdir[256], base[64], src[512], combined[640], cs[640], ws[640]; + char tmpdir[256], base[64], src[512], cs[640], ws[640]; char cmd[2048]; snprintf(tmpdir, sizeof tmpdir, "/tmp/fic_%d_b_%d", getpid(), seq); snprintf(base, sizeof base, "main815b"); snprintf(src, sizeof src, "%s/%s.ww", tmpdir, base); - snprintf(combined, sizeof combined, "%s/%s.combined.ww", tmpdir, base); - snprintf(cs, sizeof cs, "%s/%s_c.s", tmpdir, base); - snprintf(ws, sizeof ws, "%s/%s_w.s", tmpdir, base); + snprintf(cs, sizeof cs, "%s/all_cs.s", tmpdir); + snprintf(ws, sizeof ws, "%s/all_ww.s", tmpdir); mkdir(tmpdir, 0755); - if (write_source(src, r->src) != 0) { cleanup_tmp(tmpdir, base); return -1; } - - snprintf(cmd, sizeof cmd, - "cd %s && timeout 180 %s build -I %s/lib %s 2>/dev/null", - tmpdir, cdrv, cwd, src); - if (runwait(cmd) != 0) { - fprintf(stderr, "fmt_int_run[byteid][%s]: combined.ww build failed\n", - r->label); - cleanup_tmp(tmpdir, base); + if (write_source(src, r->src) != 0) { + snprintf(cmd, sizeof cmd, "rm -rf %s", tmpdir); + if (system(cmd)) {} return -1; } int rc = 0; - snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, combined); + snprintf(cmd, sizeof cmd, + "cd %s && WW_PKGCACHE=%s/pkgc_c timeout 180 %s build --sep -I %s/lib " + "-o %s/%s_c %s 2>/dev/null", tmpdir, tmpdir, cdrv, cwd, tmpdir, base, src); if (runwait(cmd) != 0) { - fprintf(stderr, "fmt_int_run[byteid][%s]: w6c errored\n", r->label); + fprintf(stderr, "fmt_int_run[byteid][%s]: cstage sep build failed\n", + r->label); rc = -1; } if (rc == 0) { - snprintf(cmd, sizeof cmd, "%s/w6c_ww -o %s %s 2>/dev/null", - bin, ws, combined); + snprintf(cmd, sizeof cmd, + "cd %s && WW_PKGCACHE=%s/pkgc_w timeout 180 %s build --sep " + "-I %s/lib -o %s/%s_w %s 2>/dev/null", + tmpdir, tmpdir, wdrv, cwd, tmpdir, base, src); if (runwait(cmd) != 0) { - fprintf(stderr, "fmt_int_run[byteid][%s]: w6c_ww errored\n", - r->label); + fprintf(stderr, "fmt_int_run[byteid][%s]: wwstage sep build " + "failed\n", r->label); rc = -1; } } if (rc == 0) { + snprintf(cmd, sizeof cmd, "cat %s/%s_c.sepwork/*.s > %s 2>/dev/null", + tmpdir, base, cs); if (system(cmd)) {} + snprintf(cmd, sizeof cmd, "cat %s/%s_w.sepwork/*.s > %s 2>/dev/null", + tmpdir, base, ws); if (system(cmd)) {} FILE *fc = fopen(cs, "rb"); FILE *fw = fopen(ws, "rb"); if (!fc || !fw) { @@ -333,8 +337,8 @@ asm_byte_identical(const char *bin, const char *cdrv, const char *cwd, r->label); } - unlink(cs); unlink(ws); - cleanup_tmp(tmpdir, base); + snprintf(cmd, sizeof cmd, "rm -rf %s", tmpdir); + if (system(cmd)) {} return rc; } @@ -382,7 +386,7 @@ main(void) if (wwpresent) { for (int i = 0; i < n; i++) { total++; - if (asm_byte_identical(bin, cdrv, cwd, &rows[i], seq++) != 0) + if (asm_byte_identical(cdrv, wdrv, cwd, &rows[i], seq++) != 0) fail++; } } else { diff --git a/test/wcc/848_xmod_qualstructlit_run.c b/test/wcc/848_xmod_qualstructlit_run.c index e8152dda..15c48a2b 100644 --- a/test/wcc/848_xmod_qualstructlit_run.c +++ b/test/wcc/848_xmod_qualstructlit_run.c @@ -290,9 +290,10 @@ static const struct scenario scenarios[] = { }; static int -run_scenario(const char *bin, const char *w6c, const char *w6c_ww, +run_scenario(const char *bin, const char *cdrv, const char *wdrv, const struct scenario *sc) { + (void)bin; char dir[] = "/tmp/ww848_XXXXXX"; if (mkdtemp(dir) == NULL) { fprintf(stderr, "848[%s]: mkdtemp failed\n", sc->label); @@ -311,12 +312,11 @@ run_scenario(const char *bin, const char *w6c, const char *w6c_ww, fclose(f); } - char comb[1024]; - snprintf(comb, sizeof comb, "%s/main.combined.ww", dir); - - /* cstage driver build + run: pins parse + runtime field values. */ - snprintf(cmd, sizeof cmd, "cd %s && %s/ww build -I %s %s/main.ww", - dir, bin, dir, dir); + /* #94 sep layout: cstage --sep build + run pins parse + runtime field + * values; pin WW_PKGCACHE under the scratch dir. */ + snprintf(cmd, sizeof cmd, + "cd %s && WW_PKGCACHE=%s/pkgc_c %s build --sep -I %s -o %s/main %s/main.ww", + dir, dir, cdrv, dir, dir, dir); if (runwait(cmd) != 0) { fprintf(stderr, "848[%s]: cstage build failed " "(qualified struct literal parse reject?)\n", sc->label); @@ -330,22 +330,25 @@ run_scenario(const char *bin, const char *w6c, const char *w6c_ww, rc = -1; } - /* rule-10 discriminator: raw w6c vs w6c_ww on the driver-produced - * combined.ww must be byte-identical .s. */ + /* rule-10 discriminator: the wwstage driver's --sep build emits + * per-package w6c_ww asm that must be byte-identical to cstage's. The + * root + each imported pkg compile to separate .sepwork/.s; + * concat (sorted glob, identical set both stages) for the compare. */ char cs_s[1024], ws_s[1024]; - snprintf(cs_s, sizeof cs_s, "%s/cs.s", dir); - snprintf(ws_s, sizeof ws_s, "%s/ww.s", dir); - snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, cs_s, comb); + snprintf(cmd, sizeof cmd, + "cd %s && WW_PKGCACHE=%s/pkgc_w %s build --sep -I %s -o %s/mainww %s/main.ww", + dir, dir, wdrv, dir, dir, dir); if (runwait(cmd) != 0) { - fprintf(stderr, "848[%s]: w6c on combined failed\n", sc->label); - rc = -1; goto done; - } - snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c_ww, ws_s, comb); - if (runwait(cmd) != 0) { - fprintf(stderr, "848[%s]: w6c_ww on combined failed " + fprintf(stderr, "848[%s]: ww_ww build failed " "(qualified struct literal parse reject?)\n", sc->label); rc = -1; goto done; } + snprintf(cs_s, sizeof cs_s, "%s/all_cs.s", dir); + snprintf(ws_s, sizeof ws_s, "%s/all_ww.s", dir); + snprintf(cmd, sizeof cmd, "cat %s/main.sepwork/*.s > %s 2>/dev/null", + dir, cs_s); if (system(cmd)) {} + snprintf(cmd, sizeof cmd, "cat %s/mainww.sepwork/*.s > %s 2>/dev/null", + dir, ws_s); if (system(cmd)) {} if (slurp_eq(cs_s, ws_s) != 0) { fprintf(stderr, "848[%s]: cs.s/ww.s DIFFER (rule-10 byte-id " "violation)\n", sc->label); @@ -371,13 +374,13 @@ main(void) bin = absbin; } - char w6c[2100], w6c_ww[2100], wwdump[2100], wwdump_ww[2100]; - snprintf(w6c, sizeof w6c, "%s/w6c", bin); - snprintf(w6c_ww, sizeof w6c_ww, "%s/w6c_ww", bin); + char cdrv[2100], wdrv[2100], wwdump[2100], wwdump_ww[2100]; + snprintf(cdrv, sizeof cdrv, "%s/ww", bin); + snprintf(wdrv, sizeof wdrv, "%s/ww_ww", bin); snprintf(wwdump, sizeof wwdump, "%s/wwdump", bin); snprintf(wwdump_ww, sizeof wwdump_ww, "%s/wwdump_ww", bin); - if (access(w6c_ww, X_OK) != 0 || access(wwdump_ww, X_OK) != 0) { - fprintf(stderr, "848: w6c_ww/wwdump_ww missing — cannot run the " + if (access(wdrv, X_OK) != 0 || access(wwdump_ww, X_OK) != 0) { + fprintf(stderr, "848: ww_ww/wwdump_ww missing — cannot run the " "cs==ww byte-id gate (the whole point of this test)\n"); return 1; } @@ -386,7 +389,7 @@ main(void) int na = (int)(sizeof ast_cases / sizeof ast_cases[0]); int fail = 0; for (int i = 0; i < n; i++) { - if (run_scenario(bin, w6c, w6c_ww, &scenarios[i]) != 0) + if (run_scenario(bin, cdrv, wdrv, &scenarios[i]) != 0) fail++; } for (int i = 0; i < na; i++) { diff --git a/test/wcc/911_attest_record.c b/test/wcc/911_attest_record.c index e78ba553..26f8164e 100644 --- a/test/wcc/911_attest_record.c +++ b/test/wcc/911_attest_record.c @@ -120,26 +120,35 @@ static int byteid(const char *bin) { int pid = getpid(); - char stem[256], comb[256], cs[256], ws[256], cmd[4096]; - snprintf(stem, sizeof stem, "/tmp/at911_bid_%d", pid); - snprintf(comb, sizeof comb, "%s.combined.ww", stem); - snprintf(cs, sizeof cs, "/tmp/at911_bid_c_%d.s", pid); - snprintf(ws, sizeof ws, "/tmp/at911_bid_w_%d.s", pid); + char stemc[256], stemw[256], cs[256], ws[256], cmd[4096]; + snprintf(stemc, sizeof stemc, "/tmp/at911_bid_c_%d", pid); + snprintf(stemw, sizeof stemw, "/tmp/at911_bid_w_%d", pid); + snprintf(cs, sizeof cs, "/tmp/at911_bid_cs_%d.s", pid); + snprintf(ws, sizeof ws, "/tmp/at911_bid_ws_%d.s", pid); - /* `ww test -c -o ` (compile-only) writes a lib/test-inclusive - * combined beside -o without running the harness. */ + /* #94 sep layout: `ww test -c --sep -o ` carries -T to the root + * so w6c synthesizes the test table + fork loop, and emits per-package + * asm to .sepwork/ (compile-only, no harness run; WW_PKGCACHE + * pinned to /tmp). The cstage build (w6c) and wwstage build (w6c_ww) + * must produce byte-identical asm across all packages. */ snprintf(cmd, sizeof cmd, - "%s/ww test -c -o %s test/wcc/data/attest_record.ww > /dev/null 2>&1", - bin, stem); - runwait(cmd); - if (access(comb, 0) != 0) { - fprintf(stderr, "911 FAIL: ww test -c produced no %s\n", comb); + "WW_PKGCACHE=/tmp/at911_pkgc_c_%d %s/ww test -c --sep -o %s " + "test/wcc/data/attest_record.ww > /dev/null 2>&1", pid, bin, stemc); + if (runwait(cmd) != 0) { + fprintf(stderr, "911 FAIL: cstage ww test -c --sep\n"); return 1; } - snprintf(cmd, sizeof cmd, "%s/w6c -T %s -o %s 2>/dev/null", bin, comb, cs); - if (runwait(cmd) != 0) { fprintf(stderr, "911 FAIL: w6c -T (byteid)\n"); return 1; } - snprintf(cmd, sizeof cmd, "%s/w6c_ww -T %s -o %s 2>/dev/null", bin, comb, ws); - if (runwait(cmd) != 0) { fprintf(stderr, "911 FAIL: w6c_ww -T (byteid)\n"); return 1; } + snprintf(cmd, sizeof cmd, + "WW_PKGCACHE=/tmp/at911_pkgc_w_%d %s/ww_ww test -c --sep -o %s " + "test/wcc/data/attest_record.ww > /dev/null 2>&1", pid, bin, stemw); + if (runwait(cmd) != 0) { + fprintf(stderr, "911 FAIL: wwstage ww_ww test -c --sep\n"); + return 1; + } + snprintf(cmd, sizeof cmd, "cat %s.sepwork/*.s > %s 2>/dev/null", stemc, cs); + if (system(cmd)) {} + snprintf(cmd, sizeof cmd, "cat %s.sepwork/*.s > %s 2>/dev/null", stemw, ws); + if (system(cmd)) {} char bc[262144], bw[262144]; int rc = 0; @@ -150,10 +159,11 @@ byteid(const char *bin) fprintf(stderr, "911 FAIL: -T asm differs between stages\n"); rc = 1; } - unlink(comb); unlink(cs); unlink(ws); - snprintf(cmd, sizeof cmd, "%s.s", stem); unlink(cmd); - snprintf(cmd, sizeof cmd, "%s.o", stem); unlink(cmd); - unlink(stem); + unlink(cs); unlink(ws); + snprintf(cmd, sizeof cmd, "rm -rf %s.sepwork %s.sepwork %s %s " + "/tmp/at911_pkgc_c_%d /tmp/at911_pkgc_w_%d", + stemc, stemw, stemc, stemw, pid, pid); + if (system(cmd)) {} return rc; } diff --git a/test/wcc/940_global_sret_run.c b/test/wcc/940_global_sret_run.c index 2e8c56b0..4fa8b0e2 100644 --- a/test/wcc/940_global_sret_run.c +++ b/test/wcc/940_global_sret_run.c @@ -135,20 +135,23 @@ static const struct row rows[] = { 0 }, }; -/* Compile the combined.ww (left next to the source by `ww build`) with - * both compilers and assert byte-identical asm. Returns 0 ok, 1 differ, - * -1 harness error. */ +/* #94 sep layout: concat the per-package asm the cstage sep build emitted + * (/gsret_c_.sepwork) and the wwstage sep build emitted + * (/gsret_w_.sepwork), then assert byte-identical. Returns 0 ok, + * 1 differ, -1 harness error. */ static int -byteid(const char *bin, const char *combined, const char *dir, int i) +byteid(const char *dir, int i) { char cs[256], ws[256], cmd[1024]; snprintf(cs, sizeof cs, "%s/bid_cs_%d.s", dir, i); snprintf(ws, sizeof ws, "%s/bid_ww_%d.s", dir, i); - snprintf(cmd, sizeof cmd, "%s/w6c %s > %s", bin, combined, cs); - if (runwait(cmd) != 0) return -1; - snprintf(cmd, sizeof cmd, "%s/w6c_ww %s > %s", bin, combined, ws); - if (runwait(cmd) != 0) return -1; + snprintf(cmd, sizeof cmd, "cat %s/gsret_c_%d.sepwork/*.s > %s 2>/dev/null", + dir, i, cs); + if (system(cmd)) {} + snprintf(cmd, sizeof cmd, "cat %s/gsret_w_%d.sepwork/*.s > %s 2>/dev/null", + dir, i, ws); + if (system(cmd)) {} snprintf(cmd, sizeof cmd, "cmp -s %s %s", cs, ws); int rc = runwait(cmd); @@ -156,12 +159,12 @@ byteid(const char *bin, const char *combined, const char *dir, int i) return rc == 0 ? 0 : 1; } -/* Build `r` with `driver` in `dir`, run the binary, return its exit - * code (or -1 on build failure). `combined_out` receives the path of - * the generated .combined.ww. */ +/* Build `r` with `driver` via `--sep -o /` (per-package asm in + * /.sepwork/), run the binary, return its exit code (or -1 on + * build failure). `cachetag` keys a private WW_PKGCACHE. */ static int run_driver(const char *driver, const struct row *r, const char *dir, - int i, char *combined_out, size_t combined_sz) + int i, const char *stem, const char *cachetag) { char src[256], cmd[1024]; snprintf(src, sizeof src, "%s/gsret_%d.ww", dir, i); @@ -171,7 +174,9 @@ run_driver(const char *driver, const struct row *r, const char *dir, fputs(r->src, f); fclose(f); - snprintf(cmd, sizeof cmd, "cd %s && %s build %s", dir, driver, src); + snprintf(cmd, sizeof cmd, + "cd %s && WW_PKGCACHE=%s/pkgc_%s %s build --sep -o %s/%s %s", + dir, dir, cachetag, driver, dir, stem, src); if (runwait(cmd) != 0) { fprintf(stderr, "row[%s]: build via %s failed\n", r->label, driver); @@ -179,10 +184,7 @@ run_driver(const char *driver, const struct row *r, const char *dir, } char outbin[256]; - snprintf(outbin, sizeof outbin, "%s/gsret_%d", dir, i); - if (combined_out) - snprintf(combined_out, combined_sz, - "%s/gsret_%d.combined.ww", dir, i); + snprintf(outbin, sizeof outbin, "%s/%s", dir, stem); return runwait(outbin); } @@ -217,12 +219,8 @@ main(void) int total = 0, fail = 0; for (int i = 0; i < n; i++) { - char combined[300]; - combined[0] = '\0'; - - /* cstage: build + run + capture combined.ww path. */ - int gc = run_driver(cdrv, &rows[i], dir, i, - combined, sizeof combined); + /* cstage: --sep build + run → /gsret_c_.sepwork/. */ + int gc = run_driver(cdrv, &rows[i], dir, i, "gsret_c", "c"); total++; if (gc != rows[i].want) { fprintf(stderr, "global_sret_run[cstage][%s]: " @@ -231,21 +229,9 @@ main(void) fail++; } - /* byte-id (rule 10): cs.s == ww.s on the same combined.ww. */ - if (have_wwc && combined[0]) { - total++; - int bid = byteid(bin, combined, dir, i); - if (bid != 0) { - fprintf(stderr, "global_sret_run[byteid][%s]: " - "%s\n", rows[i].label, - bid == 1 ? "cs.s != ww.s" : "harness error"); - fail++; - } - } - - /* wwstage: build + run. */ + /* wwstage: --sep build + run → /gsret_w_.sepwork/. */ if (have_ww) { - int gw = run_driver(wdrv, &rows[i], dir, i, NULL, 0); + int gw = run_driver(wdrv, &rows[i], dir, i, "gsret_w", "w"); total++; if (gw != rows[i].want) { fprintf(stderr, "global_sret_run[wwstage][%s]: " @@ -253,14 +239,29 @@ main(void) rows[i].want); fail++; } + + /* byte-id (rule 10): the per-package w6c asm (cstage sep + * build) == the w6c_ww asm (wwstage sep build). */ + if (have_wwc) { + total++; + int bid = byteid(dir, i); + if (bid != 0) { + fprintf(stderr, "global_sret_run[byteid][%s]: " + "%s\n", rows[i].label, + bid == 1 ? "cs.s != ww.s" + : "harness error"); + fail++; + } + } } - char p[256]; + char p[640]; snprintf(p, sizeof p, "%s/gsret_%d.ww", dir, i); unlink(p); - snprintf(p, sizeof p, "%s/gsret_%d", dir, i); unlink(p); - snprintf(p, sizeof p, "%s/gsret_%d.combined.ww", dir, i); unlink(p); - snprintf(p, sizeof p, "%s/gsret_%d.s", dir, i); unlink(p); - snprintf(p, sizeof p, "%s/gsret_%d.o", dir, i); unlink(p); + snprintf(p, sizeof p, "rm -rf %s/gsret_c_%d.sepwork " + "%s/gsret_w_%d.sepwork %s/gsret_c_%d %s/gsret_w_%d " + "%s/pkgc_c %s/pkgc_w", dir, i, dir, i, dir, i, dir, i, + dir, dir); + if (system(p)) {} } rmdir(dir); diff --git a/test/wcc/949_xmod_fnptr_const_run.c b/test/wcc/949_xmod_fnptr_const_run.c index 3fffde26..e2fc3c8c 100644 --- a/test/wcc/949_xmod_fnptr_const_run.c +++ b/test/wcc/949_xmod_fnptr_const_run.c @@ -164,16 +164,19 @@ static const struct scenario scenarios[] = { { "nonfn_dotted_table", nonfn_dotted_files, K_BUILDERR, 0 }, }; -/* Build via `driver` in the fixture dir; returns the driver's build rc and - * (for K_RUN) runs the produced binary, comparing exit to want_exit. */ +/* Build `driver build --sep -o /` in the fixture dir; returns + * the driver's build rc and (for K_RUN) runs the produced binary, comparing + * exit to want_exit. #94: the per-package asm lands in /.sepwork/ + * (cachetag keys a private WW_PKGCACHE so out/.pkgcache is untouched). */ static int -build_run(const char *dir, const char *driver, const struct scenario *sc) +build_run(const char *dir, const char *driver, const struct scenario *sc, + const char *stem, const char *cachetag) { char cmd[4096], path[1024]; snprintf(cmd, sizeof cmd, - "cd %s && rm -f main main.s main.o main.combined.ww && " - "%s build -I %s %s/main.ww >/dev/null 2>%s/err", - dir, driver, dir, dir, dir); + "cd %s && WW_PKGCACHE=%s/pkgc_%s %s build --sep -I %s -o %s/%s " + "%s/main.ww >/dev/null 2>%s/err", + dir, dir, cachetag, driver, dir, dir, stem, dir, dir); int brc = runwait(cmd); if (sc->kind == K_BUILDERR) { if (brc == 0) { @@ -187,7 +190,7 @@ build_run(const char *dir, const char *driver, const struct scenario *sc) fprintf(stderr, "949[%s]: %s build failed\n", sc->label, driver); return -1; } - snprintf(path, sizeof path, "%s/main", dir); + snprintf(path, sizeof path, "%s/%s", dir, stem); int got = runwait(path); if (got != sc->want_exit) { fprintf(stderr, "949[%s]: %s exit %d, want %d\n", @@ -198,8 +201,7 @@ build_run(const char *dir, const char *driver, const struct scenario *sc) } static int -run_scenario(const char *bin, const char *w6c, const char *w6c_ww, - const struct scenario *sc) +run_scenario(const char *bin, const struct scenario *sc) { char dir[] = "/tmp/ww949_XXXXXX"; if (mkdtemp(dir) == NULL) { @@ -207,7 +209,7 @@ run_scenario(const char *bin, const char *w6c, const char *w6c_ww, return -1; } - char path[1024], cmd[4096], wwdrv[2200]; + char path[1024], cmd[4096], csdrv[2200], wwdrv[2200]; int rc = 0; for (int i = 0; sc->files[i].name; i++) { @@ -219,50 +221,30 @@ run_scenario(const char *bin, const char *w6c, const char *w6c_ww, fclose(f); } - /* cstage driver build (+run for K_RUN). */ - { - char csdrv[2200]; - snprintf(csdrv, sizeof csdrv, "%s/ww", bin); - if (build_run(dir, csdrv, sc) != 0) { rc = -1; goto done; } - } + /* cstage driver --sep build (+run for K_RUN) → /main_c.sepwork/. */ + snprintf(csdrv, sizeof csdrv, "%s/ww", bin); + if (build_run(dir, csdrv, sc, "main_c", "c") != 0) { rc = -1; goto done; } - /* wwstage driver build (+run for K_RUN) — race-free in the private - * mktemp dir. Direct proof the wwstage emits a runnable binary. */ + /* wwstage driver --sep build (+run for K_RUN) — race-free in the + * private mktemp dir. Direct proof the wwstage emits a runnable + * binary. Distinct stem so its sepwork doesn't clobber cstage's. */ snprintf(wwdrv, sizeof wwdrv, "%s/ww_ww", bin); - if (build_run(dir, wwdrv, sc) != 0) { rc = -1; goto done; } + if (build_run(dir, wwdrv, sc, "main_w", "w") != 0) { rc = -1; goto done; } if (sc->kind == K_BUILDERR) goto done; /* Byte-id net (#263 — the wwstage-correctness proof on a gate-blind - * align-BOTH fix): raw w6c vs w6c_ww on the cstage-driver combined. */ + * align-BOTH fix): the per-package w6c-emitted .s (cstage sep build) + * vs w6c_ww-emitted .s (wwstage sep build) must be byte-identical. + * Concat each stem's per-package sepwork asm (sorted glob = same set). */ { - char cs_s[1024], ws_s[1024], comb[1024]; - /* regen the combined via the cstage driver (deterministic). */ - snprintf(cmd, sizeof cmd, - "cd %s && %s/ww build -I %s %s/main.ww >/dev/null 2>&1", - dir, bin, dir, dir); - if (runwait(cmd) != 0) { - fprintf(stderr, "949[%s]: combined regen failed\n", - sc->label); - rc = -1; goto done; - } - snprintf(comb, sizeof comb, "%s/main.combined.ww", dir); - snprintf(cs_s, sizeof cs_s, "%s/cs.s", dir); - snprintf(ws_s, sizeof ws_s, "%s/ww.s", dir); - snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", - w6c, cs_s, comb); - if (runwait(cmd) != 0) { - fprintf(stderr, "949[%s]: w6c on combined failed\n", - sc->label); - rc = -1; goto done; - } - snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", - w6c_ww, ws_s, comb); - if (runwait(cmd) != 0) { - fprintf(stderr, "949[%s]: w6c_ww on combined failed\n", - sc->label); - rc = -1; goto done; - } + char cs_s[1024], ws_s[1024]; + snprintf(cs_s, sizeof cs_s, "%s/all_cs.s", dir); + snprintf(ws_s, sizeof ws_s, "%s/all_ww.s", dir); + snprintf(cmd, sizeof cmd, "cat %s/main_c.sepwork/*.s > %s 2>/dev/null", + dir, cs_s); if (system(cmd)) {} + snprintf(cmd, sizeof cmd, "cat %s/main_w.sepwork/*.s > %s 2>/dev/null", + dir, ws_s); if (system(cmd)) {} if (slurp_eq(cs_s, ws_s) != 0) { fprintf(stderr, "949[%s]: cs.s/ww.s DIFFER (rule-10 " "byte-id violation)\n", sc->label); @@ -289,11 +271,10 @@ main(void) bin = absbin; } - char w6c[2100], w6c_ww[2100]; - snprintf(w6c, sizeof w6c, "%s/w6c", bin); - snprintf(w6c_ww, sizeof w6c_ww, "%s/w6c_ww", bin); - if (access(w6c_ww, X_OK) != 0) { - fprintf(stderr, "949: w6c_ww missing — cannot run the cs==ww " + char wdrv[2100]; + snprintf(wdrv, sizeof wdrv, "%s/ww_ww", bin); + if (access(wdrv, X_OK) != 0) { + fprintf(stderr, "949: ww_ww missing — cannot run the cs==ww " "byte-id gate (the whole point of this test)\n"); return 1; } @@ -301,7 +282,7 @@ main(void) int n = (int)(sizeof scenarios / sizeof scenarios[0]); int fail = 0; for (int i = 0; i < n; i++) { - if (run_scenario(bin, w6c, w6c_ww, &scenarios[i]) != 0) + if (run_scenario(bin, &scenarios[i]) != 0) fail++; } diff --git a/test/wcc/951_defdim_struct_run.c b/test/wcc/951_defdim_struct_run.c index 51e40203..396a0ee7 100644 --- a/test/wcc/951_defdim_struct_run.c +++ b/test/wcc/951_defdim_struct_run.c @@ -149,11 +149,10 @@ main(void) bin = absbin; } - char w6c[1100], w6c_ww[1100]; - snprintf(w6c, sizeof w6c, "%s/w6c", bin); - snprintf(w6c_ww, sizeof w6c_ww, "%s/w6c_ww", bin); - if (access(w6c_ww, X_OK) != 0) { - fprintf(stderr, "defdim_struct: w6c_ww missing — cannot run " + char wdrv[1100]; + snprintf(wdrv, sizeof wdrv, "%s/ww_ww", bin); + if (access(wdrv, X_OK) != 0) { + fprintf(stderr, "defdim_struct: ww_ww missing — cannot run " "the cs==ww byte-id gate (the whole point of this test)\n"); return 1; } @@ -172,17 +171,6 @@ main(void) getpid(), i); mkdir(tmpdir, 0755); - char cmd[2048]; - snprintf(cmd, sizeof cmd, "cd %s && %s/ww build %s", - tmpdir, bin, src); - if (runwait(cmd) != 0) { - fprintf(stderr, "row[%s]: cstage build failed\n", - rows[i].label); - fail++; - unlink(src); rmdir(tmpdir); - continue; - } - char base[64]; const char *b = strrchr(src, '/'); b = b ? b + 1 : src; @@ -190,21 +178,30 @@ main(void) char *dot = strrchr(base, '.'); if (dot && strcmp(dot, ".ww") == 0) *dot = '\0'; - char outbin[160], combined[96], arto[96], arts[96]; - /* `ww build` writes the runnable binary into the build cwd - * (tmpdir) but its intermediates — the concatenated module - * source .combined.ww, plus .o/.s — next to the SOURCE. The - * byte-id leg compiles that combined form, not the raw src: - * w6c does no import resolution, so the cross-module row's - * `import os` only folds once concatenated. A same-module row - * combines to itself, so the one path serves every row. */ - snprintf(outbin, sizeof outbin, "%s/%s", tmpdir, base); - snprintf(combined, sizeof combined, - "/tmp/wwdds_%d_%d.combined.ww", getpid(), i); - snprintf(arto, sizeof arto, "/tmp/wwdds_%d_%d.o", getpid(), i); - snprintf(arts, sizeof arts, "/tmp/wwdds_%d_%d.s", getpid(), i); + /* #94 sep layout: each driver's --sep build emits the runnable + * binary at + per-package asm under .sepwork/. + * Distinct stems so the wwstage sepwork doesn't clobber cstage's; + * pin WW_PKGCACHE under tmpdir so out/.pkgcache is untouched. A + * cross-module row's `import os` resolves per-package, a same- + * module row is just __root — both compare via the sorted glob. */ + char cmd[2048], stem_c[160], stem_w[160]; + snprintf(stem_c, sizeof stem_c, "%s/%s_c", tmpdir, base); + snprintf(stem_w, sizeof stem_w, "%s/%s_w", tmpdir, base); - int got = runwait(outbin); + snprintf(cmd, sizeof cmd, + "cd %s && WW_PKGCACHE=%s/pkgc_c %s/ww build --sep -o %s %s", + tmpdir, tmpdir, bin, stem_c, src); + if (runwait(cmd) != 0) { + fprintf(stderr, "row[%s]: cstage build failed\n", + rows[i].label); + fail++; + unlink(src); + snprintf(cmd, sizeof cmd, "rm -rf %s", tmpdir); + if (system(cmd)) {} + continue; + } + + int got = runwait(stem_c); if (got != rows[i].want_exit) { fprintf(stderr, "row[%s]: cstage exit %d, want %d\n", rows[i].label, got, rows[i].want_exit); @@ -217,19 +214,21 @@ main(void) snprintf(ws_s, sizeof ws_s, "/tmp/wwdds_%d_%d_ww.s", getpid(), i); - snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", - w6c, cs_s, combined); + snprintf(cmd, sizeof cmd, + "cd %s && WW_PKGCACHE=%s/pkgc_w %s/ww_ww build --sep -o %s %s " + ">/dev/null 2>&1", tmpdir, tmpdir, bin, stem_w, src); if (runwait(cmd) != 0) { - fprintf(stderr, "row[%s]: w6c failed\n", rows[i].label); + fprintf(stderr, "row[%s]: ww_ww build failed\n", + rows[i].label); fail++; } else { - snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", - w6c_ww, ws_s, combined); - if (runwait(cmd) != 0) { - fprintf(stderr, "row[%s]: w6c_ww failed\n", - rows[i].label); - fail++; - } else if (slurp_eq(cs_s, ws_s) != 0) { + snprintf(cmd, sizeof cmd, + "cat %s.sepwork/*.s > %s 2>/dev/null", stem_c, cs_s); + if (system(cmd)) {} + snprintf(cmd, sizeof cmd, + "cat %s.sepwork/*.s > %s 2>/dev/null", stem_w, ws_s); + if (system(cmd)) {} + if (slurp_eq(cs_s, ws_s) != 0) { fprintf(stderr, "row[%s]: cstage/wwstage .s DIFFER " "(rule-10 byte-id violation)\n", @@ -238,8 +237,8 @@ main(void) } } - unlink(outbin); rmdir(tmpdir); - unlink(combined); unlink(arto); unlink(arts); + snprintf(cmd, sizeof cmd, "rm -rf %s", tmpdir); + if (system(cmd)) {} unlink(src); unlink(cs_s); unlink(ws_s); } diff --git a/test/wcc/989_callarg_typecheck.c b/test/wcc/989_callarg_typecheck.c index 4934a016..56a65f88 100644 --- a/test/wcc/989_callarg_typecheck.c +++ b/test/wcc/989_callarg_typecheck.c @@ -294,18 +294,19 @@ static const struct trow trows[] = { "@test fn checkfoo() void = { return; };\n" }, }; -/* tbundle_reject — bundle `src` via `drv test -c`, then `comp -T` the - * combined unit; the compile must exit nonzero. Returns 0 on the - * expected reject. */ +/* tbundle_reject — #94 sep layout: ` test --sep` carries -T into the + * root unit's w6c pass, where the __wwtests reservation / call-arg + * typecheck must loud-reject, so the driver build must exit nonzero. + * `stage` is the cs/ww label; `drv` is the matching driver (ww / ww_ww). + * Returns 0 on the expected reject. */ static int -tbundle_reject(const char *bin, const char *comp, const char *drv, +tbundle_reject(const char *bin, const char *stage, const char *drv, const struct trow *t, int i) { int pid = getpid(); - char src[128], stem[128], comb[160], cmd[4096]; - snprintf(src, sizeof src, "/tmp/catt_%s_%d_%d.ww", comp, pid, i); - snprintf(stem, sizeof stem, "/tmp/catt_%s_%d_%d", comp, pid, i); - snprintf(comb, sizeof comb, "%s.combined.ww", stem); + char src[160], stem[160], cmd[4096]; + snprintf(src, sizeof src, "/tmp/catt_%s_%d_%d.ww", stage, pid, i); + snprintf(stem, sizeof stem, "/tmp/catt_%s_%d_%d", stage, pid, i); FILE *f = fopen(src, "wb"); if (!f) return -1; @@ -313,27 +314,17 @@ tbundle_reject(const char *bin, const char *comp, const char *drv, fclose(f); snprintf(cmd, sizeof cmd, - "%s/%s test -c -o %s %s > /dev/null 2>&1", bin, drv, stem, src); - runwait(cmd); - if (access(comb, 0) != 0) { - fprintf(stderr, "callarg_typecheck[%s][%s]: %s produced no %s\n", - comp, t->label, drv, comb); - unlink(src); - return -1; - } - - snprintf(cmd, sizeof cmd, "%s/%s -T %s -o /dev/null 2>/dev/null", - bin, comp, comb); + "WW_PKGCACHE=%s.pkgc %s/%s test --sep -o %s %s > /dev/null 2>&1", + stem, bin, drv, stem, src); int rc = runwait(cmd); - unlink(src); unlink(comb); - char tmp[200]; - snprintf(tmp, sizeof tmp, "%s.s", stem); unlink(tmp); - snprintf(tmp, sizeof tmp, "%s.o", stem); unlink(tmp); - unlink(stem); + unlink(src); + snprintf(cmd, sizeof cmd, "rm -rf %s %s.sepwork %s.pkgc", + stem, stem, stem); + if (system(cmd)) {} if (rc == 0) { - fprintf(stderr, "callarg_typecheck[%s][%s]: %s -T accepted " - "(expected a loud reject)\n", comp, t->label, comp); + fprintf(stderr, "callarg_typecheck[%s][%s]: %s test --sep " + "accepted (expected a loud reject)\n", stage, t->label, drv); return -1; } return 0; @@ -444,10 +435,9 @@ main(void) bin = absbin; } - char cdrv[1024], wdrv[1024], wcomp[1024]; + char cdrv[1024], wdrv[1024]; snprintf(cdrv, sizeof cdrv, "%s/ww", bin); snprintf(wdrv, sizeof wdrv, "%s/ww_ww", bin); - snprintf(wcomp, sizeof wcomp, "%s/w6c_ww", bin); struct { const char *name; const char *drv; int gated; } drivers[] = { @@ -488,17 +478,17 @@ main(void) } } - /* -T faces: comp ∈ {w6c (cstage), w6c_ww (wwstage)}; bundle is built - * by the cstage driver (compiler-neutral). wwstage gated. */ + /* -T faces: the reject fires inside each driver's --sep w6c/-T pass + * (cstage via ww, wwstage via ww_ww). wwstage gated on ww_ww. */ for (int i = 0; i < tn; i++) { total++; - if (tbundle_reject(bin, "w6c", "ww", &trows[i], i) != 0) + if (tbundle_reject(bin, "cstage", "ww", &trows[i], i) != 0) fail++; } - if (access(wcomp, X_OK) == 0) { + if (access(wdrv, X_OK) == 0) { for (int i = 0; i < tn; i++) { total++; - if (tbundle_reject(bin, "w6c_ww", "ww", &trows[i], + if (tbundle_reject(bin, "wwstage", "ww_ww", &trows[i], 10 + i) != 0) fail++; } @@ -513,7 +503,7 @@ main(void) " built ok, expected reject\n"); fail++; } - if (access(wcomp, X_OK) == 0) { /* wwstage gated (ww_ww present) */ + if (access(wdrv, X_OK) == 0) { /* wwstage gated (ww_ww present) */ total++; if (multimod_build_fail(wdrv, COLLIDE_SHAPE_MISMATCH, 0, 2) != 0) { fprintf(stderr, "callarg_typecheck[wwstage]" diff --git a/test/wcc/989_m1mangle_run.c b/test/wcc/989_m1mangle_run.c index db97f212..75eb4cb4 100644 --- a/test/wcc/989_m1mangle_run.c +++ b/test/wcc/989_m1mangle_run.c @@ -139,10 +139,15 @@ run_build(const char *driver, const struct row *r, int i) return -2; if (write_file(dir, "main.ww", r->root) != 0) return -2; - /* cd into the build dir so the source-dir-first search path finds the - * sibling package tree (mirrors Hare's CWD == module-dir). */ - snprintf(cmd, sizeof cmd, "cd '%s' && %s build main.ww 2>/dev/null", - dir, driver); + /* #94 sep layout: cd into the build dir so the source-dir-first search + * path finds the sibling package tree (mirrors Hare's CWD == + * module-dir); --sep emits per-package units to main.sepwork/ and links + * the runnable binary at main. Pin WW_PKGCACHE under the temp dir so + * out/.pkgcache is untouched. #99 (imported-pkg `fn main` mangle under + * sep) is what makes the imported_main row link here. */ + snprintf(cmd, sizeof cmd, + "cd '%s' && WW_PKGCACHE='%s/pkgc' %s build --sep -o main main.ww " + "2>/dev/null", dir, dir, driver); int brc = runwait(cmd); int got = -1; diff --git a/test/wcc/989_m2wwi_run.c b/test/wcc/989_m2wwi_run.c index 684f5061..11bc099b 100644 --- a/test/wcc/989_m2wwi_run.c +++ b/test/wcc/989_m2wwi_run.c @@ -122,19 +122,23 @@ positive(const char *bin, const char *cwd, const char *pkg, int idx) goto out; } - /* Drive the package file as the build target → its decls are the - * PRIMARY module (imported==0) of the resolved unit; the producer's - * primary filter then yields exactly this package's interface. The - * library has no main, so the build's link step fails — the - * `.combined.ww` is written before codegen (cf 989_lib_byteid), and - * only it matters here, so the exit code is deliberately ignored. */ + /* #94 sep layout: drive the package file as the --sep build target → + * its decls are the PRIMARY module of the resolved ROOT unit, which the + * producer's primary filter narrows to exactly this package's + * interface. The root unit's amalgamated source is composed at + * .sepwork/__root.unit.ww BEFORE codegen; the library has no + * main so the link step fails, but the unit (the only thing that + * matters here) is already written, so the exit code is deliberately + * ignored. WW_PKGCACHE is pinned under td so out/.pkgcache is + * untouched. */ snprintf(cmd, sizeof cmd, - "cd %s && timeout 180 %s/ww build -I %s/lib %s.ww >/dev/null 2>&1", - td, bin, cwd, pkg); + "cd %s && WW_PKGCACHE=%s/pkgc timeout 180 %s/ww build --sep " + "-I %s/lib -o %s/%s %s.ww >/dev/null 2>&1", + td, td, bin, cwd, td, pkg, pkg); runwait(cmd); char comb[1100], cs[1100], ws[1100]; - snprintf(comb, sizeof comb, "%s/%s.combined.ww", td, pkg); + snprintf(comb, sizeof comb, "%s/%s.sepwork/__root.unit.ww", td, pkg); snprintf(cs, sizeof cs, "%s/cs.wwi", td); snprintf(ws, sizeof ws, "%s/ww.wwi", td); if (access(comb, 0) != 0) {