diff --git a/Makefile b/Makefile index 9e4db92b..be84882e 100644 --- a/Makefile +++ b/Makefile @@ -510,7 +510,6 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \ $(BIN)/test_strings_run \ $(BIN)/test_hex_run $(BIN)/test_utf8_run $(BIN)/test_bytes_run \ $(BIN)/test_path_run \ - $(BIN)/test_letshadow_run \ $(BIN)/test_test_filter \ $(BIN)/test_strconv_int_run \ $(BIN)/test_stof_run $(BIN)/test_ftos_run \ @@ -2727,10 +2726,6 @@ $(BIN)/test_path_run: test/wcc/989_path_run.c $(BIN)/ww $(BIN)/w6c \ $(BIN)/w6a $(BIN)/w6l $(LIB)/libwwrt.a | $(BIN) $(CC) $(CFLAGS) -o $@ $< -$(BIN)/test_letshadow_run: test/wcc/989_letshadow_run.c $(BIN)/ww $(BIN)/w6c \ - $(BIN)/w6a $(BIN)/w6l $(LIB)/libwwrt.a | $(BIN) - $(CC) $(CFLAGS) -o $@ $< - $(BIN)/test_ascii_run: test/wcc/904_ascii_run.c $(BIN)/ww $(BIN)/w6c \ $(BIN)/w6a $(BIN)/w6l $(LIB)/libwwrt.a | $(BIN) $(CC) $(CFLAGS) -o $@ $< @@ -3269,7 +3264,7 @@ test-lang: all LANGBYTEID_DIR = $(OUT)/langbyteid LANGBYTEID_FILES = $(filter-out %_runonly_test.ww,$(wildcard test/lang/*_test.ww)) LANGBYTEID_VERB = test -c -LANGBYTEID_EXPECTED_MIN = 56 +LANGBYTEID_EXPECTED_MIN = 57 $(if $(LANGBYTEID_FILES),,$(error test-lang-byteid: empty corpus)) test-lang-byteid: all @set -e; \ diff --git a/test/wcc/989_letshadow.ww b/test/lang/letshadow_test.ww similarity index 58% rename from test/wcc/989_letshadow.ww rename to test/lang/letshadow_test.ww index 83aa051b..71dd0d95 100644 --- a/test/wcc/989_letshadow.ww +++ b/test/lang/letshadow_test.ww @@ -1,19 +1,13 @@ -// letshadow — #152 regression pin. A `let` binding must NOT be visible -// during its OWN initializer: `let x = f(x)` evaluates f(x) in the OUTER -// scope (Hare: harec check.c clet runs cexpr before scope_define). Both -// stages once linked the binding into the cgen localfind chain BEFORE -// emitting the init, so the init read the fresh UNINIT shadow slot — a -// silent miscompile identical on both stages (byte-id GREEN over it), so -// this is a RUNTIME assertion. Signalled-then-exit(+10) pinpoints the row. +// letshadow_test — #152 regression pin, migrated from test/wcc/989_letshadow_run.c. // -// Run with `out/bin/ww run test/wcc/989_letshadow.ww`; exit 0 = all pass. +// A `let` binding must NOT be visible during its OWN initializer: +// `let x = f(x)` evaluates f(x) in the OUTER scope (Hare: harec check.c clet +// runs cexpr before scope_define). Both stages once linked the binding into +// the cgen localfind chain BEFORE emitting the init, so the init read the +// fresh UNINIT shadow slot — a silent miscompile IDENTICAL on both stages +// (byte-id was GREEN over it), now fixed. PRIMITIVE-only (i32) asserts. -package main; - -import os; - -let signalled: i32 = 0; -fn fail() void = { os.exit(signalled + 10); }; +package letshadow_test; fn id(s: str) str = { return s; }; @@ -60,10 +54,18 @@ fn arrlitselfref() i32 = { return r; }; -export fn main() i32 = { - signalled = 1; if (paramshadow("hello") != 604) { fail(); }; - signalled = 2; if (letinletinit() != 6) { fail(); }; - signalled = 3; if (renamecontrol("hi") != 2) { fail(); }; - signalled = 4; if (arrlitselfref() != 6) { fail(); }; - return 0; +@test fn param_self_shadow() void = { + assert(paramshadow("hello") == 604i32); +}; + +@test fn let_in_let_init() void = { + assert(letinletinit() == 6i32); +}; + +@test fn rename_control() void = { + assert(renamecontrol("hi") == 2i32); +}; + +@test fn arrlit_self_ref() void = { + assert(arrlitselfref() == 6i32); }; diff --git a/test/wcc/989_letshadow_run.c b/test/wcc/989_letshadow_run.c deleted file mode 100644 index 9236e994..00000000 --- a/test/wcc/989_letshadow_run.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 989_letshadow_run — #152 regression pin. Compile + run the letshadow - * fixture under the C-side `ww run` driver (cstage w6c) and assert exit 0. - * - * The bug (link-the-let-before-its-init) miscompiled IDENTICALLY on both - * stages, so byte-id 990-997 is blind to it; only a runtime value check - * catches the regression. Same thin-wrapper shape as 989_path_run. - */ -#include -#include -#include -#include - -static int -runwait(const char *cmd) -{ - int rc = system(cmd); - if (rc == -1) return -1; - if (WIFEXITED(rc)) return WEXITSTATUS(rc); - return 1; -} - -int -main(void) -{ - const char *bin = getenv("BIN"); - if (!bin) bin = "out/bin"; - char absbin[1024]; - 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 cwd[1024]; - if (getcwd(cwd, sizeof cwd) == NULL) return 1; - - const char *src = "test/wcc/989_letshadow.ww"; - char path[1024], cmd[2048]; - snprintf(path, sizeof path, "%s/%s", cwd, src); - snprintf(cmd, sizeof cmd, "%s/ww run %s", bin, path); - int rc = runwait(cmd); - if (rc != 0) { - fprintf(stderr, "letshadow_run FAIL: %s exited %d " - "(row %d miscompiled — #152)\n", src, rc, rc - 10); - return 1; - } - printf("letshadow_run: %s ok\n", src); - return 0; -}