/* * 771_widen_transitive — residual artifact owner. * * Symmetric runtime and rejection coverage lives in wwfixture under * test/wcc/data/r771_*. This wrapper retains only compiler-output byte * identity plus the intentionally C-stage-only spread runtime row. */ #include #include #include #include #include #include struct row { const char *label; const char *src; const char *fixture; int byte_id; int cstage_run; int expected_exit; }; static const struct row rows[] = { { "spread_alt_widen", "package main;\n" "type underread = !i32;\n" "type nomem = !void;\n" "type wrapper = !(underread | nomem);\n" "export fn main() i32 = {\n" " let u: underread;\n" " let r: (size | ...wrapper) = u;\n" " if (r is underread) { return 70; };\n" " return 99;\n" "};\n", NULL, 0, 1, 70 }, { "direct_flat_variant", NULL, "test/wcc/data/r771_direct_flat_variant/case.ww", 1, 0, 71 }, { "branched_callee_widen", NULL, "test/wcc/data/r771_branched_callee_widen/case.ww", 1, 0, 72 }, { "wrapper_typed_widen", NULL, "test/wcc/data/r771_wrapper_typed_widen/case.ww", 1, 0, 73 }, }; static int runwait(const char *cmd) { int rc = system(cmd); if (rc == -1) return -1; if (WIFEXITED(rc)) return WEXITSTATUS(rc); return -1; } static int write_source(const char *path, const char *src) { FILE *f = fopen(path, "wb"); if (!f) return -1; int rc = fputs(src, f) == EOF ? -1 : 0; if (fclose(f) != 0) rc = -1; return rc; } static int materialize_source(const char *cwd, const struct row *r, const char *dst) { if (r->src) return write_source(dst, r->src); char path[1024], buf[4096]; snprintf(path, sizeof path, "%s/%s", cwd, r->fixture); FILE *in = fopen(path, "rb"); if (!in) return -1; FILE *out = fopen(dst, "wb"); if (!out) { fclose(in); return -1; } int rc = 0; for (;;) { size_t n = fread(buf, 1, sizeof buf, in); if (n != 0 && fwrite(buf, 1, n, out) != n) { rc = -1; break; } if (n < sizeof buf) { if (ferror(in)) rc = -1; break; } } if (fclose(out) != 0) rc = -1; fclose(in); return rc; } static int cleanup_tmp(const char *tmpdir, const char *base) { char p[640]; int rc = 0; snprintf(p, sizeof p, "%s/%s.ww", tmpdir, base); if (unlink(p) != 0 && errno != ENOENT) rc = -1; snprintf(p, sizeof p, "%s/%s", tmpdir, base); if (unlink(p) != 0 && errno != ENOENT) rc = -1; snprintf(p, sizeof p, "rm -rf %s/%s.sepwork", tmpdir, base); if (runwait(p) != 0) rc = -1; if (rmdir(tmpdir) != 0) rc = -1; return rc; } static int build_via_driver(const char *driver, const char *tmpdir, const char *cwd, const char *src, int asm_only) { char cmd[2048]; (void)cwd; snprintf(cmd, sizeof cmd, "cd %s && b='%s'; timeout 180 %s build %s" "-o \"${b%%.ww}\" \"$b\" 2>/dev/null", tmpdir, src, driver, asm_only ? "-S " : ""); return runwait(cmd); } static int run_cstage(const char *driver, const char *cwd, const struct row *r, int seq) { (void)seq; char td[] = "/tmp/r771_r_XXXXXX"; char src[512], base[64], exe[768]; if (mkdtemp(td) == NULL) return -1; snprintf(base, sizeof base, "main771"); snprintf(src, sizeof src, "%s/%s.ww", td, base); int rc = -1; if (materialize_source(cwd, r, src) != 0) goto out; rc = build_via_driver(driver, td, cwd, src, 0); if (rc == 0) { snprintf(exe, sizeof exe, "%s/%s", td, base); rc = runwait(exe); } out: if (cleanup_tmp(td, base) != 0) { fprintf(stderr, "widen_transitive[%s]: run cleanup failed\n", r->label); rc = -1; } return rc; } static int asm_byte_identical(const char *cdrv, const char *wdrv, const char *cwd, const struct row *r, int seq) { (void)seq; char tc[] = "/tmp/r771_c_XXXXXX"; char tw[] = "/tmp/r771_w_XXXXXX"; char src[512], base[64], cs[512], ws[512]; snprintf(base, sizeof base, "main771"); if (mkdtemp(tc) == NULL) return -1; if (mkdtemp(tw) == NULL) { if (cleanup_tmp(tc, base) != 0) fprintf(stderr, "widen_transitive[%s]: setup cleanup failed\n", r->label); return -1; } int rc = -1; snprintf(src, sizeof src, "%s/%s.ww", tc, base); if (materialize_source(cwd, r, src) != 0) goto out; if (build_via_driver(cdrv, tc, cwd, src, 1) != 0) goto out; snprintf(cs, sizeof cs, "%s/%s.sepwork/__root.s", tc, base); snprintf(src, sizeof src, "%s/%s.ww", tw, base); if (materialize_source(cwd, r, src) != 0) goto out; if (build_via_driver(wdrv, tw, cwd, src, 1) != 0) goto out; snprintf(ws, sizeof ws, "%s/%s.sepwork/__root.s", tw, base); FILE *fc = fopen(cs, "rb"), *fw = fopen(ws, "rb"); if (fc && fw) { rc = 0; for (;;) { int a = fgetc(fc), b = fgetc(fw); if (a != b) { rc = -1; break; } if (a == EOF) break; } } if (fc) fclose(fc); if (fw) fclose(fw); out: if (cleanup_tmp(tc, base) != 0) { fprintf(stderr, "widen_transitive[%s]: c cleanup failed\n", r->label); rc = -1; } if (cleanup_tmp(tw, base) != 0) { fprintf(stderr, "widen_transitive[%s]: ww cleanup failed\n", r->label); rc = -1; } return rc; } int main(void) { char cwd[512]; if (!getcwd(cwd, sizeof cwd)) return 1; const char *bin = getenv("BIN"); if (!bin) bin = "out/bin"; char absbin[1024]; if (bin[0] != '/') { snprintf(absbin, sizeof absbin, "%s/%s", cwd, bin); bin = absbin; } char cdrv[1200], wdrv[1200]; snprintf(cdrv, sizeof cdrv, "%s/ww", bin); snprintf(wdrv, sizeof wdrv, "%s/ww_ww", bin); int fail = 0, total = 0, seq = 0; int wwpresent = access(wdrv, X_OK) == 0; for (size_t i = 0; i < sizeof rows / sizeof rows[0]; i++) { if (rows[i].cstage_run) { total++; int got = run_cstage(cdrv, cwd, &rows[i], seq++); if (got != rows[i].expected_exit) { fprintf(stderr, "widen_transitive[cstage-only run][%s]: exit=%d want=%d\n", rows[i].label, got, rows[i].expected_exit); fail++; } } if (wwpresent && rows[i].byte_id) { total++; if (asm_byte_identical(cdrv, wdrv, cwd, &rows[i], seq++) != 0) { fprintf(stderr, "widen_transitive[byte-id][%s]: assembly differs\n", rows[i].label); fail++; } } } if (!wwpresent) fprintf(stderr, "widen_transitive: skip byte-id (no %s)\n", wdrv); if (fail) { fprintf(stderr, "widen_transitive: %d/%d residual gates failed\n", fail, total); return 1; } printf("widen_transitive: %d/%d residual gates ok\n", total, total); return 0; }