parse: enforce strict-package — reject package-less files (#24a)
Flip the soft-default to a hard "missing package clause" error symmetrically in both stages (cmd/wcc/parse.c + lib/ww/syntax/parse.ww): the first real decl of a primary section with empty pathmod/resetmod and no seen clause is now rejected. Closes the documented soft-default divergence (the 63-wrapper carve-out). The gate flip can't be split from the migration it breaks, so this is one atomic commit: ~80 test/wcc wrappers gain `package main;` via a shared wwtestpkg.h helper, 6 data fixtures plus 17 asm-grep assertions update for the bare->main.<leaf> root-helper mangle shift, and rt/ declares `package rt;` with @symbol pinning the bare rt_ensure/rt_malloc linker names. Root mangling narrows: the executable entry `main` stays bare (existing carve-out), but root helper symbols become main.X. The #84 cluster is rewritten to assert main.run distinct from aa.run/test.run; its cgen fix and bare machinery are retained — still load-bearing for package-less module-reset deps. New table-driven test 782_strict_package.c (6 rows, both stages). Retiring //ww:module-reset is deferred to #24b: it is load-bearing (clears the .wwi pathmod so the body's package clause asserts), not a vestige; fusing its removal here would be a silent mismatch. All byte-id gates green; full make test reports "all 335 tests passed".
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
must_parse(const char *src)
|
||||
@@ -18,10 +19,12 @@ must_parse(const char *src)
|
||||
Arena *a = newarena();
|
||||
Lex l;
|
||||
Parser p;
|
||||
lexinit(&l, a, "<test>", src, strlen(src));
|
||||
char *ws = wwtest_wrap(src);
|
||||
lexinit(&l, a, "<test>", ws, strlen(ws));
|
||||
parserinit(&p, a, &l);
|
||||
Node *n = parsefile(&p);
|
||||
int ok = (n != NULL && p.errs == 0 && l.errs == 0);
|
||||
free(ws);
|
||||
freearena(a);
|
||||
return ok;
|
||||
}
|
||||
@@ -32,7 +35,8 @@ parse_to_str(const char *src, int *errs)
|
||||
Arena *a = newarena();
|
||||
Lex l;
|
||||
Parser p;
|
||||
lexinit(&l, a, "<test>", src, strlen(src));
|
||||
char *ws = wwtest_wrap(src);
|
||||
lexinit(&l, a, "<test>", ws, strlen(ws));
|
||||
parserinit(&p, a, &l);
|
||||
Node *n = parsefile(&p);
|
||||
*errs = p.errs + l.errs;
|
||||
@@ -41,6 +45,7 @@ parse_to_str(const char *src, int *errs)
|
||||
size_t len = 0;
|
||||
FILE *f = open_memstream(&buf, &len);
|
||||
if (f == NULL) {
|
||||
free(ws);
|
||||
freearena(a);
|
||||
return NULL;
|
||||
}
|
||||
@@ -51,6 +56,7 @@ parse_to_str(const char *src, int *errs)
|
||||
memcpy(out, buf, len);
|
||||
out[len] = '\0';
|
||||
free(buf);
|
||||
free(ws);
|
||||
freearena(a);
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runrow(const char *src, const char *expect)
|
||||
@@ -16,7 +17,8 @@ runrow(const char *src, const char *expect)
|
||||
Lex l;
|
||||
Parser p;
|
||||
Checker c;
|
||||
lexinit(&l, a, "<test>", src, strlen(src));
|
||||
char *ws = wwtest_wrap(src);
|
||||
lexinit(&l, a, "<test>", ws, strlen(ws));
|
||||
parserinit(&p, a, &l);
|
||||
Node *file = parsefile(&p);
|
||||
|
||||
@@ -44,6 +46,7 @@ runrow(const char *src, const char *expect)
|
||||
" src: %s\n", expect, errbuf, src);
|
||||
}
|
||||
free(errbuf);
|
||||
free(ws);
|
||||
freearena(a);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
run6c(const char *src, char **out)
|
||||
@@ -16,7 +17,7 @@ run6c(const char *src, char **out)
|
||||
snprintf(path, sizeof path, "/tmp/wwt_%d.ww", getpid());
|
||||
FILE *f = fopen(path, "wb");
|
||||
if (f == NULL) return -1;
|
||||
fputs(src, f);
|
||||
wwtest_fputs(src, f);
|
||||
fclose(f);
|
||||
|
||||
char cmd[256];
|
||||
@@ -60,7 +61,7 @@ static const struct row rows[] = {
|
||||
{ "fn cond(x: i32) i32 = { if (x > 0) { return 1; }; return 0; };",
|
||||
"CMPQ\t$0, AX" },
|
||||
{ "fn lo() void = { for (let i: i32 = 0; i < 10; i += 1) { }; };", "JMP" },
|
||||
{ "fn callit() i32 = { return 1; };", "TEXT callit,$0" },
|
||||
{ "fn callit() i32 = { return 1; };", "TEXT main.callit,$0" },
|
||||
};
|
||||
|
||||
int
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
run(const char *cmd)
|
||||
@@ -35,7 +36,7 @@ main(void)
|
||||
int n = 0, fail = 0;
|
||||
for (int i = 0; programs[i]; i++, n++) {
|
||||
FILE *f = fopen(src, "wb");
|
||||
fputs(programs[i], f);
|
||||
wwtest_fputs(programs[i], f);
|
||||
fclose(f);
|
||||
|
||||
char cmd[512];
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
int
|
||||
main(void)
|
||||
@@ -20,7 +21,7 @@ main(void)
|
||||
snprintf(exe, sizeof exe, "/tmp/wwt_%d.x", getpid());
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
fputs("fn main() i32 = { return 42; };", f);
|
||||
wwtest_fputs("fn main() i32 = { return 42; };", f);
|
||||
fclose(f);
|
||||
|
||||
char cmd[1024];
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int run(const char *cmd) { return system(cmd); }
|
||||
|
||||
@@ -33,24 +34,26 @@ main(void)
|
||||
snprintf(dir, sizeof dir, "/tmp/wwarch_%d", getpid());
|
||||
mkdir(dir, 0755);
|
||||
|
||||
/* lib_good.ww — defines f1() */
|
||||
/* lib_good.ww — defines f1() (→ main.f1 under strict-package #24a) */
|
||||
char path[256];
|
||||
snprintf(path, sizeof path, "%s/lib_good.ww", dir);
|
||||
FILE *f = fopen(path, "wb");
|
||||
fputs("export fn f1() i32 = { return 7; };", f);
|
||||
wwtest_fputs("export fn f1() i32 = { return 7; };", f);
|
||||
fclose(f);
|
||||
|
||||
/* lib_bad.ww — defines f2() but also references an undefined extern */
|
||||
snprintf(path, sizeof path, "%s/lib_bad.ww", dir);
|
||||
f = fopen(path, "wb");
|
||||
fputs("@symbol(\"this_symbol_does_not_exist\") fn bogus() i32;\n"
|
||||
wwtest_fputs("@symbol(\"this_symbol_does_not_exist\") fn bogus() i32;\n"
|
||||
"export fn f2() i32 = { return bogus(); };", f);
|
||||
fclose(f);
|
||||
|
||||
/* main.ww — calls f1, NOT f2 */
|
||||
/* main.ww — calls f1, NOT f2. The plain prototype declares f1 in the
|
||||
* same (main) module, so the call resolves to main.f1 — matching
|
||||
* lib_good's moduled definition (no @symbol bare-pin needed). */
|
||||
snprintf(path, sizeof path, "%s/m.ww", dir);
|
||||
f = fopen(path, "wb");
|
||||
fputs("@symbol(\"f1\") fn f1() i32;\n"
|
||||
wwtest_fputs("fn f1() i32;\n"
|
||||
"fn main() i32 = { return f1(); };", f);
|
||||
fclose(f);
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
run_exit(const char *cmd)
|
||||
@@ -33,7 +34,7 @@ build_and_run(const char *bin, const char *prog)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(prog, f);
|
||||
wwtest_fputs(prog, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/ww run %s", bin, src);
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -142,7 +143,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s 2>/dev/null",
|
||||
@@ -174,7 +175,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, src);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static const char *
|
||||
absbin(void)
|
||||
@@ -98,10 +99,10 @@ main(void)
|
||||
|
||||
/* a standalone main.o (no undefs) + an unrelated archived foo.o. */
|
||||
FILE *f = fopen(src, "wb");
|
||||
fputs("fn main() i32 = { return 42; };", f);
|
||||
wwtest_fputs("fn main() i32 = { return 42; };", f);
|
||||
fclose(f);
|
||||
f = fopen(fsrc, "wb");
|
||||
fputs("export fn foo() i32 = { return 7; };", f);
|
||||
wwtest_fputs("export fn foo() i32 = { return 7; };", f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s", bin, asmf, src);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -149,7 +150,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -355,7 +356,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s",
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -297,7 +298,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s",
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -294,7 +295,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -153,7 +154,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s",
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -504,7 +505,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -162,7 +163,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
mkdir(tmpdir, 0755);
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s 2>/dev/null",
|
||||
@@ -194,7 +195,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, src);
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
/* want == BYTEID_ONLY: the row cannot LINK/run (a slice-of-struct
|
||||
* module global does not data-emit yet — separate gap), so only the
|
||||
@@ -138,7 +139,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s 2>/dev/null",
|
||||
@@ -169,7 +170,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, src);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -250,7 +251,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -228,7 +229,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -101,7 +102,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s",
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -316,7 +317,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -277,7 +278,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -223,7 +224,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s",
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -301,7 +302,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
@@ -332,7 +333,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, src);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -1812,7 +1813,7 @@ main(void)
|
||||
snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", tmpdir);
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
fputs(rows[i].src, f);
|
||||
wwtest_fputs(rows[i].src, f);
|
||||
fclose(f);
|
||||
|
||||
char cmd[1024];
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -291,7 +292,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
@@ -322,7 +323,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, src);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -156,7 +157,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
@@ -185,7 +186,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, src);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -149,7 +150,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
@@ -178,7 +179,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, src);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -201,7 +202,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
@@ -230,7 +231,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, src);
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -221,7 +222,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
@@ -250,7 +251,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, src);
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -310,7 +311,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
@@ -341,7 +342,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, src);
|
||||
|
||||
@@ -80,6 +80,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -273,7 +274,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s",
|
||||
|
||||
@@ -110,6 +110,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -347,7 +348,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s 2>/dev/null",
|
||||
@@ -379,7 +380,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, src);
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -216,7 +217,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -193,7 +194,7 @@ run_row(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s >/dev/null 2>&1",
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -148,7 +149,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s",
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -222,7 +223,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
mkdir(tmpdir, 0755);
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s",
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -190,7 +191,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -144,7 +145,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
@@ -175,7 +176,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, src);
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -146,7 +147,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
@@ -177,7 +178,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, src);
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -232,7 +233,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s",
|
||||
@@ -308,7 +309,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
int rc = 0;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -52,44 +53,44 @@ static const struct row rows[] = {
|
||||
/* Scalar i8 = -1 → low byte 0xff, then 7 bytes of sign-extension. */
|
||||
{ "i8_neg", "let x: i8 = -1i8;\n"
|
||||
"fn main() i32 = { return 0; };\n",
|
||||
"x",
|
||||
"main.x",
|
||||
"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff" },
|
||||
/* Scalar i16 = -2 → 0xfe 0xff then 6 byte sign extension. */
|
||||
{ "i16_neg", "let x: i16 = -2i16;\n"
|
||||
"fn main() i32 = { return 0; };\n",
|
||||
"x",
|
||||
"main.x",
|
||||
"\\xfe\\xff\\xff\\xff\\xff\\xff\\xff\\xff" },
|
||||
/* Scalar i32 = -100 → 0x9C 0xFF 0xFF 0xFF then 4 byte sign extension. */
|
||||
{ "i32_neg", "let x: i32 = -100i32;\n"
|
||||
"fn main() i32 = { return 0; };\n",
|
||||
"x",
|
||||
"main.x",
|
||||
"\\x9c\\xff\\xff\\xff\\xff\\xff\\xff\\xff" },
|
||||
/* Scalar i64 = -1000 → 0xfffffffffffffc18 little-endian. */
|
||||
{ "i64_neg", "let x: i64 = -1000i64;\n"
|
||||
"fn main() i32 = { return 0; };\n",
|
||||
"x",
|
||||
"main.x",
|
||||
"\\x18\\xfc\\xff\\xff\\xff\\xff\\xff\\xff" },
|
||||
/* Array [4]i8 = [1, -2, 3, -4] → 0x01 0xfe 0x03 0xfc. */
|
||||
{ "i8_arr", "let a: [4]i8 = [1i8, -2i8, 3i8, -4i8];\n"
|
||||
"fn main() i32 = { return 0; };\n",
|
||||
"a",
|
||||
"main.a",
|
||||
"\\x01\\xfe\\x03\\xfc" },
|
||||
/* Array [4]i16 = [1, -2, 3, -4] → LE16 each. */
|
||||
{ "i16_arr", "let a: [4]i16 = [1i16, -2i16, 3i16, -4i16];\n"
|
||||
"fn main() i32 = { return 0; };\n",
|
||||
"a",
|
||||
"main.a",
|
||||
"\\x01\\x00\\xfe\\xff\\x03\\x00\\xfc\\xff" },
|
||||
/* Array [3]i32 = [10, -20, 30] → LE32 each. */
|
||||
{ "i32_arr", "let a: [3]i32 = [10i32, -20i32, 30i32];\n"
|
||||
"fn main() i32 = { return 0; };\n",
|
||||
"a",
|
||||
"main.a",
|
||||
"\\x0a\\x00\\x00\\x00\\xec\\xff\\xff\\xff\\x1e\\x00\\x00\\x00" },
|
||||
/* Array [2]i64 = [100, -200] → LE64 each. Note 100 == 'd' and
|
||||
* 56 == '8' are printable ASCII so emit_data_byte writes them
|
||||
* raw rather than as `\xNN`. */
|
||||
{ "i64_arr", "let a: [2]i64 = [100i64, -200i64];\n"
|
||||
"fn main() i32 = { return 0; };\n",
|
||||
"a",
|
||||
"main.a",
|
||||
"d\\x00\\x00\\x00\\x00\\x00\\x00\\x00"
|
||||
"8\\xff\\xff\\xff\\xff\\xff\\xff\\xff" },
|
||||
};
|
||||
@@ -128,7 +129,7 @@ emit_s(const char *w6c, const struct row *r, int i, char *out_s, size_t cap)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -125,7 +126,7 @@ check_pushdx_before_pushax(const char *spath, const struct row *r)
|
||||
long off = 0;
|
||||
int saw_site = 0;
|
||||
for (;;) {
|
||||
long call = find_after(buf, off, "CALL\tyield_");
|
||||
long call = find_after(buf, off, "CALL\tmain.yield_");
|
||||
if (call < 0) break;
|
||||
saw_site = 1;
|
||||
long pdx = find_after(buf, call, "PUSHQ\tDX");
|
||||
@@ -162,7 +163,7 @@ emit_s(const char *w6c, const struct row *r, int i, char *out_s, size_t cap)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -144,7 +145,7 @@ emit_s(const char *w6c, const struct row *r, int i, char *out_s, size_t cap)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
@@ -164,8 +165,8 @@ check_leaq_di_before_call(const char *path, const struct row *r)
|
||||
char line[1024];
|
||||
int ok = -1;
|
||||
while (fgets(line, sizeof line, f)) {
|
||||
if (strstr(line, "CALL\tmk(SB)")
|
||||
|| strstr(line, "CALL mk(SB)")) {
|
||||
if (strstr(line, "CALL\tmain.mk(SB)")
|
||||
|| strstr(line, "CALL main.mk(SB)")) {
|
||||
if (strstr(prev, "LEAQ\t")
|
||||
&& strstr(prev, "(BP), DI")) {
|
||||
ok = 0;
|
||||
@@ -199,7 +200,7 @@ check_movq_bp_ax_before_ret(const char *path, const struct row *r)
|
||||
int ok = -1;
|
||||
while (fgets(line, sizeof line, f)) {
|
||||
if (!in_mk) {
|
||||
if (strstr(line, "TEXT mk,") || strstr(line, "TEXT\tmk,"))
|
||||
if (strstr(line, "TEXT main.mk,") || strstr(line, "TEXT\tmain.mk,"))
|
||||
in_mk = 1;
|
||||
continue;
|
||||
}
|
||||
@@ -241,15 +242,15 @@ check_movq_bp_di_before_inner_call(const char *path, const struct row *r)
|
||||
int ok = -1;
|
||||
while (fgets(line, sizeof line, f)) {
|
||||
if (!in_mk) {
|
||||
if (strstr(line, "TEXT mk,")
|
||||
|| strstr(line, "TEXT\tmk,"))
|
||||
if (strstr(line, "TEXT main.mk,")
|
||||
|| strstr(line, "TEXT\tmain.mk,"))
|
||||
in_mk = 1;
|
||||
strncpy(prev, line, sizeof prev - 1);
|
||||
prev[sizeof prev - 1] = '\0';
|
||||
continue;
|
||||
}
|
||||
if (strstr(line, "CALL\tinner(SB)")
|
||||
|| strstr(line, "CALL inner(SB)")) {
|
||||
if (strstr(line, "CALL\tmain.inner(SB)")
|
||||
|| strstr(line, "CALL main.inner(SB)")) {
|
||||
if (strstr(prev, "MOVQ\t")
|
||||
&& strstr(prev, "(BP), DI")
|
||||
&& !strstr(prev, "LEAQ"))
|
||||
@@ -283,8 +284,8 @@ check_no_movq_ax_bp_after_call(const char *path, const struct row *r)
|
||||
int ok = 0;
|
||||
while (fgets(line, sizeof line, f)) {
|
||||
if (!seen_call) {
|
||||
if (strstr(line, "CALL\tmk(SB)")
|
||||
|| strstr(line, "CALL mk(SB)")) {
|
||||
if (strstr(line, "CALL\tmain.mk(SB)")
|
||||
|| strstr(line, "CALL main.mk(SB)")) {
|
||||
seen_call = 1;
|
||||
}
|
||||
continue;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -107,7 +108,7 @@ emit_s(const char *w6c, const struct row *r, int i, char *out_s, size_t cap)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -84,7 +85,7 @@ check_three_push_after_call(const char *spath, const struct row *r)
|
||||
char buf[1 << 16];
|
||||
if (slurp(spath, buf, sizeof buf) < 0) return -1;
|
||||
|
||||
long call = find_after(buf, 0, "CALL\tview");
|
||||
long call = find_after(buf, 0, "CALL\tmain.view");
|
||||
if (call < 0) {
|
||||
fprintf(stderr, "row[%s]: no CALL view site\n", r->label);
|
||||
return -1;
|
||||
@@ -135,7 +136,7 @@ emit_s(const char *w6c, const struct row *r, int i, char *out_s, size_t cap)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -79,7 +80,7 @@ check_movq_zero_present(const char *spath, const struct row *r)
|
||||
char buf[1 << 16];
|
||||
if (slurp(spath, buf, sizeof buf) < 0) return -1;
|
||||
|
||||
const char *body = strstr(buf, "TEXT produce");
|
||||
const char *body = strstr(buf, "TEXT main.produce");
|
||||
if (!body) {
|
||||
fprintf(stderr, "row[%s]: no TEXT produce label\n", r->label);
|
||||
return -1;
|
||||
@@ -112,7 +113,7 @@ emit_s(const char *w6c, const struct row *r, int i, char *out_s, size_t cap)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -76,7 +77,7 @@ emit_s(const char *w6c, const struct row *r, int i, char *out_s, size_t cap)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -97,7 +98,7 @@ emit_s(const char *w6c, const struct row *r, int i, char *out_s, size_t cap)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
@@ -172,7 +173,7 @@ check_movsxd_kept(const char *spath, const struct row *r, const char *stage)
|
||||
r->label, stage, spath);
|
||||
return -1;
|
||||
}
|
||||
const char *fn = strstr(buf, "TEXT promote");
|
||||
const char *fn = strstr(buf, "TEXT main.promote");
|
||||
if (!fn) {
|
||||
fprintf(stderr, "row[%s][%s]: no TEXT promote in %s\n",
|
||||
r->label, stage, spath);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -131,7 +132,7 @@ run_row(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd,
|
||||
@@ -155,7 +156,7 @@ run_row(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s run %s >/dev/null 2>&1", driver, src);
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -112,7 +113,7 @@ emit_s(const char *w6c, const struct row *r, int i, char *out_s, size_t cap)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
@@ -144,8 +145,8 @@ check_narrow_mov(const char *path, const struct row *r)
|
||||
(void)load_needle;
|
||||
while (fgets(line, sizeof line, f)) {
|
||||
if (!in_mk) {
|
||||
if (strstr(line, "TEXT mk,")
|
||||
|| strstr(line, "TEXT\tmk,"))
|
||||
if (strstr(line, "TEXT main.mk,")
|
||||
|| strstr(line, "TEXT\tmain.mk,"))
|
||||
in_mk = 1;
|
||||
continue;
|
||||
}
|
||||
@@ -188,8 +189,8 @@ check_no_movq_at_off(const char *path, const struct row *r)
|
||||
int bad = 0;
|
||||
while (fgets(line, sizeof line, f)) {
|
||||
if (!in_mk) {
|
||||
if (strstr(line, "TEXT mk,")
|
||||
|| strstr(line, "TEXT\tmk,"))
|
||||
if (strstr(line, "TEXT main.mk,")
|
||||
|| strstr(line, "TEXT\tmain.mk,"))
|
||||
in_mk = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -133,7 +134,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
/* timeout 180 per repo convention (990-997); test/run does not bound
|
||||
@@ -187,7 +188,7 @@ asm_byte_identical(const char *bin, const char *src, const char *label, int i)
|
||||
|
||||
FILE *f = fopen(wwsrc, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(src, f);
|
||||
wwtest_fputs(src, f);
|
||||
fclose(f);
|
||||
|
||||
char w6c[640], w6c_ww[640];
|
||||
@@ -255,7 +256,7 @@ xmod_fold_present(const char *w6c, const char *stage)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(xmod_src, f);
|
||||
wwtest_fputs(xmod_src, f);
|
||||
fclose(f);
|
||||
|
||||
if (emit_s(w6c, src, s, sizeof s) != 0) {
|
||||
@@ -316,7 +317,7 @@ compile_fails(const char *w6c, const struct failrow *r, const char *stage, int i
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
/* A regressed depth guard would HANG the cycle rows rather than fail
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -94,7 +95,7 @@ emit_s(const char *w6c, const char *src_text, int i, char *out_s, size_t cap)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(src_text, f);
|
||||
wwtest_fputs(src_text, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -96,7 +97,7 @@ emit_s(const char *w6c, const struct row *r, int i, char *out_s, size_t cap)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
@@ -117,7 +118,7 @@ check_loadmov(const char *spath, const struct row *r, const char *stage)
|
||||
r->label, stage, spath);
|
||||
return -1;
|
||||
}
|
||||
const char *fn = strstr(buf, "TEXT probe");
|
||||
const char *fn = strstr(buf, "TEXT main.probe");
|
||||
if (!fn) {
|
||||
fprintf(stderr,
|
||||
"row[%s][%s]: no TEXT probe in %s\n",
|
||||
@@ -149,7 +150,7 @@ check_inner_scale_only(const char *spath, const struct row *r,
|
||||
{
|
||||
char buf[1 << 14];
|
||||
if (slurp(spath, buf, sizeof buf) < 0) return -1;
|
||||
const char *fn = strstr(buf, "TEXT probe");
|
||||
const char *fn = strstr(buf, "TEXT main.probe");
|
||||
if (!fn) return -1;
|
||||
const char *ret = strstr(fn, "\tRET\n");
|
||||
if (!ret) ret = fn + strlen(fn);
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -98,7 +99,7 @@ emit_s(const char *w6c, const struct row *r, int i, char *out_s, size_t cap)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
@@ -119,7 +120,7 @@ check_storemov(const char *spath, const struct row *r, const char *stage)
|
||||
r->label, stage, spath);
|
||||
return -1;
|
||||
}
|
||||
const char *fn = strstr(buf, "TEXT probe");
|
||||
const char *fn = strstr(buf, "TEXT main.probe");
|
||||
if (!fn) {
|
||||
fprintf(stderr,
|
||||
"row[%s][%s]: no TEXT probe in %s\n",
|
||||
@@ -164,7 +165,7 @@ check_inner_scale_only(const char *spath, const struct row *r,
|
||||
{
|
||||
char buf[1 << 14];
|
||||
if (slurp(spath, buf, sizeof buf) < 0) return -1;
|
||||
const char *fn = strstr(buf, "TEXT probe");
|
||||
const char *fn = strstr(buf, "TEXT main.probe");
|
||||
if (!fn) return -1;
|
||||
const char *ret = strstr(fn, "\tRET\n");
|
||||
if (!ret) ret = fn + strlen(fn);
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -126,7 +127,7 @@ emit_s(const char *w6c, const struct row *r, int i, char *out_s, size_t cap)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
@@ -146,7 +147,7 @@ check_probe(const char *spath, const struct row *r, const char *stage)
|
||||
r->label, stage, spath);
|
||||
return -1;
|
||||
}
|
||||
const char *fn = strstr(buf, "TEXT probe");
|
||||
const char *fn = strstr(buf, "TEXT main.probe");
|
||||
if (!fn) {
|
||||
fprintf(stderr,
|
||||
"row[%s][%s]: no TEXT probe in %s\n",
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -67,7 +68,7 @@ check_caller_stores(const char *spath)
|
||||
char buf[1 << 16];
|
||||
if (slurp(spath, buf, sizeof buf) < 0) return -1;
|
||||
|
||||
const char *body = strstr(buf, "TEXT main");
|
||||
const char *body = strstr(buf, "TEXT main,");
|
||||
if (!body) {
|
||||
fprintf(stderr, "variadic_pack: no TEXT main label\n");
|
||||
return -1;
|
||||
@@ -118,7 +119,7 @@ emit_s(const char *w6c, char *out_s, size_t cap, int tag)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(src_text, f);
|
||||
wwtest_fputs(src_text, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -200,7 +201,7 @@ check_copy_loads(const char *spath, const struct row *r)
|
||||
static char buf[1 << 16];
|
||||
if (slurp(spath, buf, sizeof buf) < 0) return -1;
|
||||
|
||||
const char *body = strstr(buf, "TEXT produce");
|
||||
const char *body = strstr(buf, "TEXT main.produce");
|
||||
if (!body) {
|
||||
fprintf(stderr, "row[%s]: no TEXT produce label in %s\n",
|
||||
r->label, spath);
|
||||
@@ -233,7 +234,7 @@ emit_s(const char *w6c, const struct row *r, int i, int stage,
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->asm_src, f);
|
||||
wwtest_fputs(r->asm_src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
@@ -257,7 +258,7 @@ run_driver(const char *driver, const struct row *r, int i, int stage)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->run_src, f);
|
||||
wwtest_fputs(r->run_src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s 2>/dev/null",
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -111,7 +112,7 @@ emit_s(const char *w6c, const struct row *r, int i, char *out_s, size_t cap)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
@@ -129,7 +130,7 @@ check_stride(const char *spath, const struct row *r, const char *stage)
|
||||
r->label, stage, spath);
|
||||
return -1;
|
||||
}
|
||||
const char *fn = strstr(buf, "TEXT probe");
|
||||
const char *fn = strstr(buf, "TEXT main.probe");
|
||||
if (!fn) {
|
||||
fprintf(stderr,
|
||||
"row[%s][%s]: no TEXT probe in %s\n",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -143,7 +144,7 @@ emit_s(const char *w6c, const struct row *r, int i, char *out_s, size_t cap)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null", w6c, out_s, src);
|
||||
@@ -161,7 +162,7 @@ check_stride(const char *spath, const struct row *r, const char *stage)
|
||||
r->label, stage, spath);
|
||||
return -1;
|
||||
}
|
||||
const char *fn = strstr(buf, "TEXT probe");
|
||||
const char *fn = strstr(buf, "TEXT main.probe");
|
||||
if (!fn) {
|
||||
fprintf(stderr,
|
||||
"row[%s][%s]: no TEXT probe in %s\n",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -121,7 +122,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
@@ -152,7 +153,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, src);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -158,7 +159,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s 2>/dev/null",
|
||||
@@ -191,7 +192,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, src);
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -107,7 +108,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
/* timeout 180 per repo convention; test/run does not bound
|
||||
@@ -151,7 +152,7 @@ asm_byte_identical(const char *bin, const char *src, const char *label, int i)
|
||||
|
||||
FILE *f = fopen(wwsrc, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(src, f);
|
||||
wwtest_fputs(src, f);
|
||||
fclose(f);
|
||||
|
||||
char w6c[640], w6c_ww[640];
|
||||
@@ -212,7 +213,7 @@ cstage_narrow_fails(const char *w6c)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(narrow_src, f);
|
||||
wwtest_fputs(narrow_src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "timeout 180 %s -o %s %s 2>/dev/null",
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -208,7 +209,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
/* timeout 180 per repo convention (cf. 760); test/run does not
|
||||
@@ -243,7 +244,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "timeout 180 %s/w6c -o %s %s 2>/dev/null",
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -141,7 +142,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
/* timeout 180 per repo convention (cf. 760, 761); test/run does
|
||||
@@ -176,7 +177,7 @@ asm_byte_identical(const char *bin, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "timeout 180 %s/w6c -o %s %s 2>/dev/null",
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -181,7 +182,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
/* timeout 180 per repo convention (cf. 761, 762); test/run does
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -99,7 +100,7 @@ static const struct row rows[] = {
|
||||
" return 0;\n"
|
||||
"};\n",
|
||||
NULL, NULL,
|
||||
"LEAQ\tadd1(SB)",
|
||||
"LEAQ\tmain.add1(SB)",
|
||||
STAGE_CS | STAGE_WW },
|
||||
{ "branched_callee",
|
||||
"fn aa(x: i32) i32 = { return x; };\n"
|
||||
@@ -111,7 +112,7 @@ static const struct row rows[] = {
|
||||
" return 0;\n"
|
||||
"};\n",
|
||||
NULL, NULL,
|
||||
"LEAQ\tbb(SB)",
|
||||
"LEAQ\tmain.bb(SB)",
|
||||
STAGE_CS | STAGE_WW },
|
||||
{ "alias_chain",
|
||||
"fn add1(x: i32) i32 = { return x + 1; };\n"
|
||||
@@ -121,7 +122,7 @@ static const struct row rows[] = {
|
||||
" return 0;\n"
|
||||
"};\n",
|
||||
NULL, NULL,
|
||||
"LEAQ\tadd1(SB)",
|
||||
"LEAQ\tmain.add1(SB)",
|
||||
STAGE_CS | STAGE_WW },
|
||||
{ "fn_with_args",
|
||||
"fn many(a: i32, b: i64, p: *i32) i64 = { return b; };\n"
|
||||
@@ -130,7 +131,7 @@ static const struct row rows[] = {
|
||||
" return 0;\n"
|
||||
"};\n",
|
||||
NULL, NULL,
|
||||
"LEAQ\tmany(SB)",
|
||||
"LEAQ\tmain.many(SB)",
|
||||
STAGE_CS | STAGE_WW },
|
||||
{ "fn_tuple_return",
|
||||
"fn pair() (i64, str) = { return (7: i64, \"x\"); };\n"
|
||||
@@ -139,7 +140,7 @@ static const struct row rows[] = {
|
||||
" return 0;\n"
|
||||
"};\n",
|
||||
NULL, NULL,
|
||||
"LEAQ\tpair(SB)",
|
||||
"LEAQ\tmain.pair(SB)",
|
||||
STAGE_CS | STAGE_WW },
|
||||
/* Cross-mod: cstage emits the LEAQ via N_DOT TK_AMP (already
|
||||
* working pre-#180). Wwstage bails asserttyped on the same
|
||||
@@ -156,6 +157,7 @@ static const struct row rows[] = {
|
||||
" return 0;\n"
|
||||
"};\n",
|
||||
"wcamffn764mod",
|
||||
"package wcamffn764mod;\n"
|
||||
"export fn somefn(x: i32) i32 = { return x + 1; };\n",
|
||||
"LEAQ\twcamffn764mod.somefn(SB)",
|
||||
STAGE_CS },
|
||||
@@ -181,13 +183,13 @@ write_sources(const struct row *r, char *src, size_t srcsz,
|
||||
mkdir(moddir, 0755);
|
||||
FILE *mf = fopen(modfile, "wb");
|
||||
if (!mf) return -1;
|
||||
fputs(r->modsrc, mf);
|
||||
wwtest_fputs(r->modsrc, mf);
|
||||
fclose(mf);
|
||||
}
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -144,7 +145,7 @@ write_source(const char *src_path, const char *src)
|
||||
{
|
||||
FILE *f = fopen(src_path, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(src, f);
|
||||
wwtest_fputs(src, f);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -132,7 +133,7 @@ write_source(const char *src_path, const char *src)
|
||||
{
|
||||
FILE *f = fopen(src_path, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(src, f);
|
||||
wwtest_fputs(src, f);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -182,7 +183,7 @@ write_source(const char *src_path, const char *src)
|
||||
{
|
||||
FILE *f = fopen(src_path, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(src, f);
|
||||
wwtest_fputs(src, f);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
163
test/wcc/782_strict_package.c
Normal file
163
test/wcc/782_strict_package.c
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* 782_strict_package — #24a strict-package gate, BOTH stages (w6c + w6c_ww).
|
||||
*
|
||||
* Every primary section must open with a `package` clause; a missing clause
|
||||
* on the first real decl is a hard error ("missing package clause"). An
|
||||
* imported (`//ww:module <path>`) or sep primary-reset region carries its
|
||||
* identity out-of-band and is exempt; an in-section `package` clause then
|
||||
* ASSERTS — its leaf must equal the path's last component ("package <x>
|
||||
* does not match import path <p>"). A bare `//ww:module-reset` opens a fresh
|
||||
* primary section that must itself re-declare a clause.
|
||||
*
|
||||
* Rule-10: every row runs on cstage `w6c` AND wwstage `w6c_ww`; both must
|
||||
* agree (accept/reject identically; diagnostic text differs by stage —
|
||||
* cstage `errorf` carries a position, wwstage `errmsg` is terser — so the
|
||||
* check is on a shared substring, not the whole line). Reject rows feed RAW
|
||||
* source: the `package` clause IS the unit under test, so there is no
|
||||
* auto-prepend here (unlike the migrated codegen fixtures).
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.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;
|
||||
}
|
||||
|
||||
static int
|
||||
file_contains(const char *path, const char *needle)
|
||||
{
|
||||
FILE *f = fopen(path, "r");
|
||||
if (!f) return 0;
|
||||
char line[4096];
|
||||
int found = 0;
|
||||
while (fgets(line, sizeof line, f))
|
||||
if (strstr(line, needle)) { found = 1; break; }
|
||||
fclose(f);
|
||||
return found;
|
||||
}
|
||||
|
||||
struct row {
|
||||
const char *label;
|
||||
const char *src;
|
||||
int accept; /* 1 = must compile clean; 0 = must reject */
|
||||
const char *diag; /* reject: required stderr substring (NULL on accept) */
|
||||
};
|
||||
|
||||
static const struct row rows[] = {
|
||||
/* 1: a `package main;` executable section. */
|
||||
{ "pkg_main_accept",
|
||||
"package main;\nexport fn main() i32 = { return 0; };\n",
|
||||
1, NULL },
|
||||
/* 2: no clause → hard error on the first decl. */
|
||||
{ "no_clause_reject",
|
||||
"export fn main() i32 = { return 0; };\n",
|
||||
0, "missing package clause" },
|
||||
/* 3: imported region — the clause leaf matches the path leaf. */
|
||||
{ "module_leaf_match_accept",
|
||||
"//ww:module foo\npackage foo;\nexport fn x() i32 = { return 0; };\n",
|
||||
1, NULL },
|
||||
/* 4: imported region — the clause leaf mismatches the path. */
|
||||
{ "module_leaf_mismatch_reject",
|
||||
"//ww:module foo\npackage bar;\nexport fn x() i32 = { return 0; };\n",
|
||||
0, "does not match import path" },
|
||||
/* 5: a comment-only file declares nothing, so no clause is required. */
|
||||
{ "comment_only_accept",
|
||||
"// just a comment, no decls\n",
|
||||
1, NULL },
|
||||
/* 6: a bare `//ww:module-reset` opens a fresh primary section; the
|
||||
* clause-less second section is rejected (the #84/#24a boundary). */
|
||||
{ "reset_second_section_reject",
|
||||
"package main;\nexport fn a() i32 = { return 0; };\n"
|
||||
"//ww:module-reset\nexport fn b() i32 = { return 0; };\n",
|
||||
0, "missing package clause" },
|
||||
{ NULL, NULL, 0, NULL },
|
||||
};
|
||||
|
||||
/* Compile r->src with `stage` (a w6c-family binary); verify accept/reject
|
||||
* and, on reject, the diagnostic substring. Returns 0 on success. */
|
||||
static int
|
||||
check_stage(const char *stage, const char *tag, const struct row *r,
|
||||
const char *tmpdir)
|
||||
{
|
||||
char src[256], sout[256], errf[256], cmd[2048];
|
||||
snprintf(src, sizeof src, "%s/sp_%s.ww", tmpdir, r->label);
|
||||
snprintf(sout, sizeof sout, "%s/sp_%s.s", tmpdir, r->label);
|
||||
snprintf(errf, sizeof errf, "%s/sp_%s.err", tmpdir, r->label);
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { fprintf(stderr, "782 FAIL: write %s\n", src); return 1; }
|
||||
fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>%s", stage, sout, src, errf);
|
||||
int rc = runwait(cmd);
|
||||
|
||||
if (r->accept) {
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "782 FAIL: [%s][%s] expected ACCEPT, "
|
||||
"rejected (rc=%d)\n", r->label, tag, rc);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (rc == 0) {
|
||||
fprintf(stderr, "782 FAIL: [%s][%s] expected REJECT, "
|
||||
"accepted\n", r->label, tag);
|
||||
return 1;
|
||||
}
|
||||
if (!file_contains(errf, r->diag)) {
|
||||
fprintf(stderr, "782 FAIL: [%s][%s] rejected but no `%s` "
|
||||
"on stderr\n", r->label, tag, r->diag);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 cs[1100], ww[1100], tmpdir[64], rmcmd[160];
|
||||
snprintf(cs, sizeof cs, "%s/w6c", bin);
|
||||
snprintf(ww, sizeof ww, "%s/w6c_ww", bin);
|
||||
snprintf(tmpdir, sizeof tmpdir, "/tmp/sp782_%d", getpid());
|
||||
mkdir(tmpdir, 0755);
|
||||
snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", tmpdir);
|
||||
|
||||
/* wwstage twin is gated on its presence (rule 14 / 993 pattern). */
|
||||
int have_ww = (access(ww, X_OK) == 0);
|
||||
|
||||
int fail = 0;
|
||||
for (int i = 0; rows[i].label; i++) {
|
||||
fail += check_stage(cs, "cs", &rows[i], tmpdir);
|
||||
if (have_ww)
|
||||
fail += check_stage(ww, "ww", &rows[i], tmpdir);
|
||||
}
|
||||
|
||||
runwait(rmcmd);
|
||||
if (fail) {
|
||||
fprintf(stderr, "782: %d check(s) failed\n", fail);
|
||||
return 1;
|
||||
}
|
||||
printf("strict_package: 6 rows (accept/reject + leaf-assert + bare-reset) "
|
||||
"agree on cstage w6c%s (#24a)\n", have_ww ? " and wwstage w6c_ww" : "");
|
||||
return 0;
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static char *
|
||||
run6c(const char *bin, const char *src)
|
||||
@@ -18,7 +19,7 @@ run6c(const char *bin, const char *src)
|
||||
char path[64];
|
||||
snprintf(path, sizeof path, "/tmp/wwffi_%d.ww", getpid());
|
||||
FILE *f = fopen(path, "wb");
|
||||
fputs(src, f);
|
||||
wwtest_fputs(src, f);
|
||||
fclose(f);
|
||||
|
||||
char cmd[512];
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -136,7 +137,7 @@ main(void)
|
||||
snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", tmpdir);
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
fputs(rows[i].src, f);
|
||||
wwtest_fputs(rows[i].src, f);
|
||||
fclose(f);
|
||||
|
||||
char cmd[1024];
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -171,7 +172,7 @@ run_driver(const char *driver, const struct row *r, const char *dir,
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd,
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -88,7 +89,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s", driver, outbin, src);
|
||||
|
||||
@@ -53,7 +53,8 @@ run_miss(const char *bin)
|
||||
snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", tmpdir);
|
||||
FILE *f = fopen(src, "w");
|
||||
if (!f) { fprintf(stderr, "949 FAIL: stage miss\n"); runwait(rmcmd); return 1; }
|
||||
fputs("import nosuchpkg;\n"
|
||||
fputs("package main;\n"
|
||||
"import nosuchpkg;\n"
|
||||
"export fn main() i32 = { return 0; };\n", f);
|
||||
fclose(f);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runcap(const char *cmd, char **outerr, size_t *outlen)
|
||||
@@ -42,7 +43,7 @@ writefile(const char *path, const char *src)
|
||||
{
|
||||
FILE *f = fopen(path, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(src, f);
|
||||
wwtest_fputs(src, f);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -383,7 +384,7 @@ run_driver(const char *driver, const struct row *r, int i)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { runwait(rmcmd); return -1; }
|
||||
fputs(r->src, f);
|
||||
wwtest_fputs(r->src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s build -o %s %s",
|
||||
|
||||
@@ -12,27 +12,23 @@
|
||||
* class silent miscompile, gate-blind and symmetric cs==ww. Surfaced by
|
||||
* #80's `ww test` coexist (lib/test exports `run`).
|
||||
*
|
||||
* Fixture (the minimal real repro): a dir-package `aa` exporting `run`,
|
||||
* imported by a PACKAGE-LESS root that defines its OWN bare `fn run` and
|
||||
* calls it from `main`. Package-less is REQUIRED: a `package main` root's
|
||||
* decls mangle `main.<leaf>` (the package clause sets the module), so its
|
||||
* `run` would be `main.run` — no collision with `aa.run`, vacuous. Only a
|
||||
* package-less primary yields a truly BARE `run`, the #84 trigger.
|
||||
* Strict-package (#24a) form: a dir-package `aa` exporting `run`, imported
|
||||
* by a `package main;` root that defines its OWN `fn run` and calls it from
|
||||
* `main`. The root's `run` mangles `main.run` — DISTINCT from the imported
|
||||
* `aa.run` and from the bare entry `main`. The original #84 trigger (a
|
||||
* truly BARE `run` from a PACKAGE-LESS root) is unreachable now that
|
||||
* strict-package forbids package-less primaries; the #84 cgen machinery
|
||||
* (mod_collect / mod_lookup_for_fn) stays dormant-but-load-bearing for
|
||||
* genuinely package-less `//ww:module-reset` deps until #24b/#26.
|
||||
*
|
||||
* Asserts (combined `ww build`, BOTH driver stages; the fix lives in
|
||||
* mod_collect/mod_lookup_for_fn which run in every mode, so combined is
|
||||
* the minimal repro — `--sep` reproduces identically):
|
||||
* 1. Build + run, BOTH stages → exit 9 (the USER's bare `run`, return 9),
|
||||
* Asserts (combined `ww build`, BOTH driver stages; `--sep` reproduces
|
||||
* identically):
|
||||
* 1. Build + run, BOTH stages → exit 9 (the user's `main.run`, return 9),
|
||||
* never aa.run (return 5).
|
||||
* 2. cs==ww (rule 10): the combined `.s` is byte-identical between the
|
||||
* two driver stages.
|
||||
* 3. NON-VACUITY + SOUNDNESS (the #84-specific signal): the `.s` has
|
||||
* EXACTLY ONE `TEXT run` (the user's, bare) AND EXACTLY ONE `TEXT
|
||||
* aa.run` (the import) — i.e. DISTINCT symbols, no dup. Pre-fix this
|
||||
* row fails: two `TEXT aa.run` (the user's `run` mis-mangled onto the
|
||||
* import) and zero bare `TEXT run`. (Exit alone is not a reliable
|
||||
* signal: pre-fix the dup happened to bind the user's copy under this
|
||||
* link order and still exited 9 — the label count is the proof.)
|
||||
* 3. DISTINCTNESS: the `.s` has EXACTLY ONE `TEXT main.run` (the user's)
|
||||
* AND EXACTLY ONE `TEXT aa.run` (the import) — distinct symbols, no dup.
|
||||
*
|
||||
* Light wwstage-driver test (CLAUDE.md rule 14): all intermediates are
|
||||
* `-o`-redirected to /tmp, phase-parallel-safe. Models 989_sepbuild_run.c.
|
||||
@@ -136,9 +132,13 @@ static const char *aa_src =
|
||||
"package aa;\n"
|
||||
"export fn run() i32 = { return 5; };\n";
|
||||
|
||||
/* PACKAGE-LESS root (no `package` clause) → its `fn run` is bare (the #84
|
||||
* trigger); a `package main` root would mangle it `main.run` (vacuous). */
|
||||
/* Strict-package (#24a) root: declares `package main;`, so its `fn run`
|
||||
* mangles `main.run` — DISTINCT from the imported `aa.run`, and from the
|
||||
* bare entry `main`. The bare call `run()` resolves to the local `main.run`
|
||||
* via the standard exact-hint path (the #84 special-case is bypassed for a
|
||||
* moduled root). */
|
||||
static const char *root_src =
|
||||
"package main;\n"
|
||||
"import aa;\n"
|
||||
"fn run() i32 = { return 9; };\n"
|
||||
"export fn main() i32 = { return run(); };\n";
|
||||
@@ -191,21 +191,20 @@ main(void)
|
||||
fail++;
|
||||
continue;
|
||||
}
|
||||
/* (1) the user's bare `run` (9) must win over imported aa.run (5). */
|
||||
/* (1) the user's `main.run` (9) must win over imported aa.run (5). */
|
||||
int rc = runwait(stg[s].prog);
|
||||
if (rc != 9) {
|
||||
fprintf(stderr, "84 FAIL: %s prog exit=%d expected 9 "
|
||||
"(bare user run, not aa.run=5)\n", stg[s].drv, rc);
|
||||
"(user main.run, not aa.run=5)\n", stg[s].drv, rc);
|
||||
fail++;
|
||||
}
|
||||
/* (3) distinct symbols, no dup: exactly one bare `run` + one
|
||||
* `aa.run`. Pre-fix: two `aa.run` (user run mis-mangled) + zero
|
||||
* bare `run`. */
|
||||
int nrun = count_text_label(stg[s].sfile, "run");
|
||||
/* (3) distinct symbols, no dup: exactly one `main.run` + one
|
||||
* `aa.run`. */
|
||||
int nrun = count_text_label(stg[s].sfile, "main.run");
|
||||
int naa = count_text_label(stg[s].sfile, "aa.run");
|
||||
if (nrun != 1 || naa != 1) {
|
||||
fprintf(stderr, "84 FAIL: %s labels TEXT run=%d aa.run=%d "
|
||||
"(want 1/1 — bare user run distinct from import, no dup)\n",
|
||||
fprintf(stderr, "84 FAIL: %s labels TEXT main.run=%d aa.run=%d "
|
||||
"(want 1/1 — user main.run distinct from import, no dup)\n",
|
||||
stg[s].drv, nrun, naa);
|
||||
fail++;
|
||||
}
|
||||
@@ -224,8 +223,8 @@ out:
|
||||
fprintf(stderr, "84: %d check(s) failed\n", fail);
|
||||
return 1;
|
||||
}
|
||||
printf("barefn_collide: package-less root `fn run` (bare) coexists with "
|
||||
"imported aa.run — distinct labels, no dup, user run wins (exit 9), "
|
||||
"cs==ww, both driver stages (#84)\n");
|
||||
printf("barefn_collide: `package main;` root `fn run` (main.run) coexists "
|
||||
"with imported aa.run — distinct labels, no dup, user run wins "
|
||||
"(exit 9), cs==ww, both driver stages (#84/#24a)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -114,7 +115,7 @@ write_file(const char *path, const char *body)
|
||||
{
|
||||
FILE *f = fopen(path, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(body, f);
|
||||
wwtest_fputs(body, f);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
@@ -196,12 +197,13 @@ static struct tcase cases[] = {
|
||||
/* a non-`fn() void` @test signature must loud-reject, not be coerced. */
|
||||
{ "badsig", NULL, "test/wcc/data/attest_badsig.ww", 0, 0, 1 },
|
||||
/* a user `fn run` COEXISTS with lib/test's bound runner (post-#80 synth
|
||||
* `use test;` keys the runner under "test", #84 mangles the user `run`
|
||||
* bare) → accept and run to exit 0. Under sep the two land in distinct
|
||||
* units (`run` in __root.s, `test.run` in test.s), so a regressed #84
|
||||
* collision re-mangles the user `run` to `test.run` and the force-loaded
|
||||
* root `.o` + test's `.a` both define `test.run` → w6l duplicate-symbol
|
||||
* → non-zero; exit 0 is the teeth (empirically confirmed). byteid=1 also
|
||||
* `use test;` keys the runner under "test"; under strict-package #24a the
|
||||
* user file's `package main;` mangles its `run` to `main.run`) → accept
|
||||
* and run to exit 0. Under sep the two land in distinct units (`main.run`
|
||||
* in __root.s, `test.run` in test.s), so a regressed collision re-mangles
|
||||
* the user `run` to `test.run` and the force-loaded root `.o` + test's
|
||||
* `.a` both define `test.run` → w6l duplicate-symbol → non-zero; exit 0
|
||||
* is the teeth (empirically confirmed). byteid=1 also
|
||||
* pins this coexist path's cs==ww per-pkg asm + synth presence — the
|
||||
* rule-10 leg the ported 997 `coexist_run` carried over the #84 mangle. */
|
||||
{ "collide_run", NULL, "test/wcc/data/attest_userrun.ww", 0, 1, 0 },
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -472,7 +473,7 @@ probe_ww_compile(const char *bin)
|
||||
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (!f) { fail++; continue; }
|
||||
fputs(progs[i].src, f);
|
||||
wwtest_fputs(progs[i].src, f);
|
||||
fclose(f);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "timeout 180 %s/wwdump_ww -c %s > %s 2>/dev/null",
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -129,7 +130,8 @@ run_exit_code(const char *bin, const char *driver, int code)
|
||||
snprintf(src, sizeof src, "/tmp/ww_rc_%d_%d.ww", getpid(), code);
|
||||
FILE *f = fopen(src, "w");
|
||||
if (!f) return -1;
|
||||
fprintf(f, "export fn main() i32 = {\n\treturn %d;\n};\n", code);
|
||||
fprintf(f, "package main;\nexport fn main() i32 = {\n\treturn %d;\n};\n",
|
||||
code);
|
||||
fclose(f);
|
||||
|
||||
char cmd[256];
|
||||
@@ -151,7 +153,7 @@ run_build_fail(const char *bin, const char *driver)
|
||||
snprintf(src, sizeof src, "/tmp/ww_badbuild_%d.ww", getpid());
|
||||
FILE *f = fopen(src, "w");
|
||||
if (!f) return -1;
|
||||
fputs("export fn main() i32 = {\n\treturn 1\n", f); /* no ; no } */
|
||||
wwtest_fputs("export fn main() i32 = {\n\treturn 1\n", f); /* no ; no } */
|
||||
fclose(f);
|
||||
|
||||
char cmd[256];
|
||||
@@ -178,7 +180,7 @@ run_missing_pkg(const char *bin, const char *driver)
|
||||
snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", tmpdir);
|
||||
FILE *f = fopen(src, "w");
|
||||
if (!f) { runwait(rmcmd); return 1; }
|
||||
fputs("import nosuchpkg;\nexport fn main() i32 = { return 0; };\n", f);
|
||||
wwtest_fputs("import nosuchpkg;\nexport fn main() i32 = { return 0; };\n", f);
|
||||
fclose(f);
|
||||
|
||||
/* #8: the sep scratch is mkdir'd before the import-resolution failure,
|
||||
@@ -225,7 +227,7 @@ main(void)
|
||||
{
|
||||
FILE *f = fopen(hello_src, "w");
|
||||
if (!f) return 1;
|
||||
fputs("import os;\n\n"
|
||||
wwtest_fputs("import os;\n\n"
|
||||
"export fn main() i32 = {\n"
|
||||
"\tos.write(1, \"hi\\n\".ptr, 3u64);\n"
|
||||
"\treturn 0;\n"
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include <dirent.h>
|
||||
#include "wwtestpkg.h"
|
||||
|
||||
static int
|
||||
runwait(const char *cmd)
|
||||
@@ -101,7 +102,7 @@ write_file(const char *path, const char *content)
|
||||
{
|
||||
FILE *f = fopen(path, "wb");
|
||||
if (!f) return -1;
|
||||
fputs(content, f);
|
||||
wwtest_fputs(content, f);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
// #80/#84 -T coexist — a user `fn run` COEXISTS with lib/test's bound
|
||||
// runner `run` (the synth main's callee). Once `ww test -c` bundles
|
||||
// lib/test, the synth `use test;` keys lib/test's `run` under module
|
||||
// "test" (#80: prepended before binding) and the user's package-less
|
||||
// `run` mangles to a DISTINCT bare `run` (#84) — no duplicate. Both
|
||||
// "test" (#80: prepended before binding) and the user's `package main;`
|
||||
// `run` mangles to a DISTINCT `main.run` (#84/#24a) — no duplicate. Both
|
||||
// stages accept under -T and the synth runner runs the @test to exit 0;
|
||||
// the user `run` must NOT hijack the entry. Pre-#80 this loud-rejected
|
||||
// "duplicate fn run". The gate (910/997 coexist_run) static-label-counts
|
||||
// the -T asm — exactly 1 `TEXT run` (user, bare) + 1 `TEXT test.run` (lib
|
||||
// the -T asm — exactly 1 `TEXT main.run` (user) + 1 `TEXT test.run` (lib
|
||||
// runner) — pinning #84 distinctness here in the REAL @test/-T path (a
|
||||
// dead-dup regression yields 0x run / 2x test.run). General callability of
|
||||
// the bare run is gated separately by 989_barefn_collide.
|
||||
// dead-dup regression yields 0x main.run / 2x test.run). General
|
||||
// callability of the user run is gated separately by 989_barefn_collide.
|
||||
package main;
|
||||
fn run() i32 = { return 9; };
|
||||
|
||||
@test fn t_one() void = {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// builtins into c.top, so installtop must DROP this redecl rather than
|
||||
// erroring. Both stages accept; the builtin `nomem` (= !void) wins, so
|
||||
// g()'s i32 arm returns 7. Pins the 771/774/926 shape.
|
||||
package main;
|
||||
type nomem = !void;
|
||||
fn g() (i32 | nomem) = { return 7; };
|
||||
export fn main() i32 = {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// #23 — two top-level defs of the same name in one (flat) module.
|
||||
// cstage's install pass rejects "duplicate def D"; wwstage now mirrors.
|
||||
package main;
|
||||
def D: i32 = 1;
|
||||
def D: i32 = 2;
|
||||
export fn main() i32 = { return 0; };
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// #23 — two top-level fns of the same name in the same (flat) module.
|
||||
// cstage's install pass rejects "duplicate fn foo"; wwstage now mirrors.
|
||||
package main;
|
||||
fn foo() i32 = { return 1; };
|
||||
fn foo() i32 = { return 2; };
|
||||
export fn main() i32 = { return foo(); };
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// #23 — two top-level lets of the same name in one (flat) module.
|
||||
// cstage's install pass rejects "duplicate let g"; wwstage now mirrors.
|
||||
package main;
|
||||
let g: i32 = 1;
|
||||
let g: i32 = 2;
|
||||
export fn main() i32 = { return 0; };
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// #23 — two top-level types of the same name in one (flat) module.
|
||||
// cstage's install pass rejects "duplicate type t"; wwstage now mirrors.
|
||||
package main;
|
||||
type t = i32;
|
||||
type t = u32;
|
||||
export fn main() i32 = { return 0; };
|
||||
|
||||
61
test/wcc/wwtestpkg.h
Normal file
61
test/wcc/wwtestpkg.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* wwtestpkg.h — strict-package (#24a) test support.
|
||||
*
|
||||
* Inline ww test fixtures historically omitted the `package main;` clause
|
||||
* that the parser now requires (a missing clause is a hard error). These
|
||||
* helpers inject it transparently so the fixtures stay terse, WITHOUT
|
||||
* disturbing fixtures that already declare their own module identity.
|
||||
*
|
||||
* wwtest_fputs is a drop-in for fputs(src, f): it prepends `package main;`
|
||||
* only when writing at the START of a fresh file (ftell == 0) AND the
|
||||
* fixture does not already open with its own `package`/`//ww:module`
|
||||
* directive. The ftell guard keeps multi-part writes and writes to
|
||||
* non-seekable streams (stderr) behaving exactly like plain fputs.
|
||||
*/
|
||||
#ifndef WWTESTPKG_H
|
||||
#define WWTESTPKG_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static inline int
|
||||
wwtest_has_module(const char *s)
|
||||
{
|
||||
const char *p = s;
|
||||
while (p != NULL) {
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
if (strncmp(p, "package ", 8) == 0
|
||||
|| strncmp(p, "package\t", 8) == 0
|
||||
|| strncmp(p, "//ww:module", 11) == 0)
|
||||
return 1;
|
||||
p = strchr(p, '\n');
|
||||
if (p != NULL)
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
wwtest_fputs(const char *src, FILE *f)
|
||||
{
|
||||
if (ftell(f) == 0 && !wwtest_has_module(src))
|
||||
fputs("package main;\n", f);
|
||||
fputs(src, f);
|
||||
}
|
||||
|
||||
/* In-process variant: a malloc'd copy of src with the clause prefixed
|
||||
* (unless src declares its own module). Caller frees. */
|
||||
static inline char *
|
||||
wwtest_wrap(const char *src)
|
||||
{
|
||||
const char *pfx = wwtest_has_module(src) ? "" : "package main;\n";
|
||||
size_t np = strlen(pfx), ns = strlen(src);
|
||||
char *b = malloc(np + ns + 1);
|
||||
memcpy(b, pfx, np);
|
||||
memcpy(b + np, src, ns + 1);
|
||||
return b;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user