Final fold-2 chunk. The 12 Fam13 single-file value drivers move from test/wcc/*_run.c into in-language @test row-tables under test/lang/: - value rows -> test/lang/*_test.ww (12 files) - reject rows -> runww //ww:error carriers (13, dual-stage non-vacuous) - nullable abort rows -> runww //ww:run-exit 1 carriers (3) - 953_globalslice_arg -> _runonly (cs!=ww checker divergence, #28) - 788 value_not_type_neg + 953_arrlit_slice reject_assign kept as slim rc-only .c pins (divergent-diag dual-reject, mutation-gated); 788 #29 Coverage parity verified row-by-row vs each retired driver; advisor- ratified carve taxonomy; two-round reviewed. Floor ratchet follows.
133 lines
4.5 KiB
C
133 lines
4.5 KiB
C
/*
|
|
* 953_arrlit_slice_run -- SLIMMED to the one irreducible asymmetric row.
|
|
*
|
|
* The #25/#31 array-literal-slice corpus migrated to fold-2 homes (#5-C6): the
|
|
* value rows -> test/lang/arrlit_slice_test.ww (@test + T2 byte-id); the
|
|
* reject_oob / reject_call / reject_ret rows -> test/wcc/data/arrlit_slice_*
|
|
* runww //ww:error carriers (strong shared substrings, both stages).
|
|
*
|
|
* reject_assign CANNOT move to a runww //ww:error carrier: both stages REJECT an
|
|
* array-LITERAL assigned to a slice, but at DIFFERENT diagnostic LAYERS -- cstage
|
|
* at assignability ("cannot assign [3]int to []i32") and wwstage at the borrow
|
|
* gate ("array literal cannot borrow as a slice here; bind it to a `let` first").
|
|
* BOTH reject CORRECTLY (the borrow is supported only at a `let` init, #31/#33) --
|
|
* this is a benign diag-LAYER divergence, NOT a miscompile, so NO bug ticket. No
|
|
* honest shared substring exists for a #20-non-vacuity carrier, and a build-reject
|
|
* emits no .s (no byte-id surface). It stays a slim C pin asserting rc!=0 BOTH
|
|
* stages -- the position the stages diverge, most worth pinning.
|
|
*
|
|
* Non-vacuity self-check (the pin CAN go RED): `valid_src` assigns a NAMED array
|
|
* (an addressable backing), which the #258 borrow ACCEPTS on both stages (rc==0);
|
|
* it proves the pin discriminates the array-LITERAL reject from a legitimate
|
|
* array-to-slice assign, not "all builds error". Mutation-checked: binding the
|
|
* literal to a `let` first (`let t=[1,2,3]; s=t;`) flips both stages to accept ->
|
|
* the reject leg goes RED (verified).
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/wait.h>
|
|
|
|
static int
|
|
runwait(const char *cmd)
|
|
{
|
|
int rc = system(cmd);
|
|
if (rc == -1) return -1;
|
|
if (WIFEXITED(rc)) return WEXITSTATUS(rc);
|
|
return -1;
|
|
}
|
|
|
|
/* reject_assign: an array LITERAL in assign position has no addressable backing
|
|
* -- both stages reject (cstage assignability, wwstage borrow gate). */
|
|
static const char *reject_src =
|
|
"package main;\n"
|
|
"export fn main() i32 = {\n"
|
|
" let s: []i32 = [0, 0];\n"
|
|
" s = [1, 2, 3];\n"
|
|
" return s[0];\n"
|
|
"};\n";
|
|
|
|
/* Vacuity control: a NAMED array assigned as a slice borrow (#258) -- both
|
|
* stages accept. Proves the pin distinguishes accept from reject. */
|
|
static const char *valid_src =
|
|
"package main;\n"
|
|
"export fn main() i32 = {\n"
|
|
" let a: [3]i32 = [1, 2, 3];\n"
|
|
" let s: []i32 = a[0:1];\n"
|
|
" s = a;\n"
|
|
" return s[0];\n"
|
|
"};\n";
|
|
|
|
/* build_only -- write `src`, build via `driver` (no run). Returns the build
|
|
* exit code (0 = accepted, nonzero = rejected). */
|
|
static int
|
|
build_only(const char *driver, const char *src, int seq)
|
|
{
|
|
char tmpdir[96], srcp[128], outbin[128], rmcmd[160], cmd[1024];
|
|
snprintf(tmpdir, sizeof tmpdir, "/tmp/as_%d_%d", getpid(), seq);
|
|
mkdir(tmpdir, 0755);
|
|
snprintf(srcp, sizeof srcp, "%s/c.ww", tmpdir);
|
|
snprintf(outbin, sizeof outbin, "%s/c", tmpdir);
|
|
snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", tmpdir);
|
|
|
|
FILE *f = fopen(srcp, "wb");
|
|
if (!f) { runwait(rmcmd); return -1; }
|
|
fputs(src, f);
|
|
fclose(f);
|
|
|
|
snprintf(cmd, sizeof cmd, "timeout 20 %s build -o %s %s >/dev/null 2>&1",
|
|
driver, outbin, srcp);
|
|
int brc = runwait(cmd);
|
|
runwait(rmcmd);
|
|
return brc;
|
|
}
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
const char *bin = getenv("BIN");
|
|
if (!bin) bin = "out/bin";
|
|
char absbin[2080];
|
|
if (bin[0] != '/') {
|
|
char cwd[1024];
|
|
if (getcwd(cwd, sizeof cwd) == NULL) return 1;
|
|
snprintf(absbin, sizeof absbin, "%s/%s", cwd, bin);
|
|
bin = absbin;
|
|
}
|
|
|
|
char cdrv[2120], wdrv[2120];
|
|
snprintf(cdrv, sizeof cdrv, "%s/ww", bin);
|
|
snprintf(wdrv, sizeof wdrv, "%s/ww_ww", bin);
|
|
|
|
int wwpresent = (access(wdrv, X_OK) == 0);
|
|
int fail = 0, seq = 0;
|
|
|
|
/* reject leg: both stages must REJECT (rc!=0). */
|
|
if (build_only(cdrv, reject_src, seq++) == 0) {
|
|
fprintf(stderr, "arrlit_slice[cs]: reject_assign ACCEPTED (want reject)\n");
|
|
fail++;
|
|
}
|
|
if (wwpresent && build_only(wdrv, reject_src, seq++) == 0) {
|
|
fprintf(stderr, "arrlit_slice[ww]: reject_assign ACCEPTED (want reject)\n");
|
|
fail++;
|
|
}
|
|
|
|
/* vacuity control: both stages must ACCEPT (rc==0). */
|
|
if (build_only(cdrv, valid_src, seq++) != 0) {
|
|
fprintf(stderr, "arrlit_slice[cs]: vacuity control REJECTED (pin may be vacuous)\n");
|
|
fail++;
|
|
}
|
|
if (wwpresent && build_only(wdrv, valid_src, seq++) != 0) {
|
|
fprintf(stderr, "arrlit_slice[ww]: vacuity control REJECTED (pin may be vacuous)\n");
|
|
fail++;
|
|
}
|
|
|
|
if (fail) {
|
|
fprintf(stderr, "arrlit_slice: %d checks failed\n", fail);
|
|
return 1;
|
|
}
|
|
printf("arrlit_slice: reject_assign pin ok\n");
|
|
return 0;
|
|
}
|