Files
ww/test/wcc/944_alias_accept_run.c
Hojun-Cho 4adf914f2f wcc_ww/cgen: #92 rhsstructpayload N_STRUCTLIT arm through structlookupchain
The N_STRUCTLIT arm still did bare structlookup on the literal's type
name — an alias-named struct LITERAL widened into a union (`type ali =
base; let v: (void|ali) = ali{...}`) missed the registered structinfo
and fell to the scalar widen arm: word0-only/dropped payload, cs 0 /
ww EXIT 1, byte-id NO (reviewer-B2 find, pre-existing at 486f7f8's
parent). Exactly the class batch-2 c2 closed for the N_IDENT-local arm
of the SAME function; same funnel fix — route through structlookupchain
(cgenutil.ww:1758) and return si.sname so every consumer's re-lookup
hits the REGISTERED name.

One pre-authorized rider: structlookupchain's entry gate accepted only
N_TNAME, but a struct literal's type ref parses as N_IDENT (expression
position, lib/ww/parse/expr.ww builds s.lhs as N_IDENT — OBSERVED).
Widened to `N_TNAME || N_IDENT`; the entry-kind predicate is spelled
twice (the early-return and the chain loop's first iteration — the
loop reassigns cur to aliaslookup results, which are always N_TNAME,
so later iterations are untouched). Consumer census, all 10 call
sites: cgenutil:3187(+this arm; post-commit position), cgenexpr:2927/3006/8775/9011,
cgenstmt:3033 guard on N_TNAME explicitly before calling;
cgenexpr:5756 (etnode = type-spec .lhs), cgenstmt:1978 (arrtn.lhs or
the synthesized #79 N_TNAME), cgenstmt:2695 (cglet n.lhs declared
type spec) pass parsetype products only — parsetype builds zero
N_IDENT nodes (lib/ww/parse/parse.ww). No existing caller can pass
N_IDENT: the widening is strictly accepting-more; existing callers
unmoved. NO second inline chase in the arm (close-by-construction).
Base spellings byte-id: structlookup hits at the chain entry and
si.sname == the literal's own name — same string out, same asm.

Pin: 944_alias_accept_run union_slit_{base_ctl,alias,alias2,order} —
base control holds 0/0; 1/2-level alias + permuted decl order graduate
cs0/ww1-byte-id-NO -> 0/0 byte-id. #63 PROBED post-c3 per the
enrollment rule: does NOT green at this site (8B alias struct-lit
let-init still ww silent-zero-fill exit 1; 16B still loud "aggregate
init from unhandled rhs shape") — its miss is the cgenstmt let-init
dispatch, not rhsstructpayload; documented on task #63, left red, no
row enrolled.

Light gates: test-unit 290 green; sizelint 0; 989 ratchet zero flips;
five-mains NEUTRAL vs master-74195ac scratch on identical inputs +
cs==ww on all five. combined.ww regens ride along (#110).
2026-06-05 23:38:54 +09:00

1154 lines
39 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 944_alias_accept_run — #5 alias arc F1: cstage acceptance ALIGN-UP
* through the transitive TY_NAMED chase (type_chase_named, promoted to
* cmd/wcc/type.c). harec dealiases at every promotion/cond/assign
* consumer (ref/harec/src/types.c:53 type_dealias; :989-996
* type_is_assignable; src/check.c:1083-1105 type_promote; :2141 if,
* :2515 for, :3229 &&/||, :3572 !) — wwstage already accepted these
* shapes AND ran them Hare-right (F0 census /tmp/f0/livelist.md), so
* the cstage single-peel rejects were the lean side aligned UP.
*
* row | shape | want
* ---------------------+--------------------------------------+-----
* binop_alias_base | myint + int (F0 m1_binop) | 0
* binop_2level | myint2 % int, myu / u32 (m1_binop2) | 0
* ret_through_2level | fn(x: myint2) int = x * 2 | 0
* assign_alias_alias | k1 → k2 (same base; harec dealias- |
* | both admits) | 0
* binop_alias_vs_alias | k1 + k2 — cstage stays LOUD per |
* | harec type_promote ALIAS+ALIAS→NULL | err(cs)
* cond_if/for/bang/ | alias-of-bool at every cond consumer |
* andor/fnparam | (F0 m2_* family) | 0
* assert_stays_loud | alias-bool assert — BOTH stages loud |
* | (F0 2a DISSOLVED-SYMMETRIC; the Hare |
* | widening is parked on #5) | err
* dot_2level | field access via a3=b3=c3=struct |
* | (task #70, ken c3_chain3) | 0
* deref_alias_ptr | *p through pi2=pi=*int | 0
* idx/slice/range_ | index/slice/for-range over 2-level |
* 2level, slice_arg | alias bases (F0 8b) — cs cgen index |
* | family chased (idx_eff + base |
* | classify); ww half landed (#60, F2a |
* | batch 1 tichase) — graduated K_RUN | 0
* arg_2level_* | task #61: alias-NAMED struct PARAM |
* | classify (fwd-ref / lit-init / 40B |
* | 5-eightbyte / f64 SSE class legs + |
* | base control) | 0
* float_alias_param* / | ken-v3 leg: 2-level f64/str/slice |
* str_alias_2level / | aliases at the cgen KIND classifiers |
* slice_alias_param | (slice leg graduated, #60 F2a b1) | 0
* slicefield_* / | reviewer-F1 leg: 2-level alias of |
* strfield_store_2lvl | slice/str as a STRUCT FIELD type — |
* | cgen field gates chased (stores, |
* | struct-lit, walk leaves, reads); |
* | unprobed gates LOUD-tripwired (#73, |
* | K_BUILDERR_CS pin) | 0
* union_store_* + | task #62 Layer-2: alias-NAMED struct |
* union_push_arg | as union member — widen store/push |
* | word0-only; cs half c138605, ww half |
* | F2a batch-2 c2 — graduated K_RUN; |
* | base ctl + #54-bound `as` row loud | 0
* union_slit_* | task #92 (F2a batch-3 c3): alias- |
* | named struct LITERAL into a union — |
* | rhsstructpayload N_STRUCTLIT arm |
* | routed through structlookupchain; |
* | base ctl + 1/2-level + decl order | 0
* nested_alias_field_* | task #71: alias-typed nested-field |
* | store/read/addr-of walks fold to |
* | direct offsets (byte-id graduation, |
* | both decl orders) | 0
*
* K_RUN rows also assert cstage/wwstage asm byte-id (acceptance
* graduations land byte-identical — F0's accept side was wwstage).
* K_RUN_CS / K_BUILDERR_CS rows run the cstage driver only, each
* citing the task that graduates them. binop_alias_vs_alias is
* CS-only loud: the wwstage checker stays silent on typed mismatches
* by design (5-lite discipline) — cs pins the harec-parity reject.
* NNN<950, self-contained (/tmp, no imports) — rule-14's selfhost-
* sibling race does not apply (941/944 precedent).
*/
#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
slurp_eq(const char *a, const char *b)
{
FILE *fa = fopen(a, "rb");
FILE *fb = fopen(b, "rb");
if (!fa || !fb) { if (fa) fclose(fa); if (fb) fclose(fb); return -1; }
int rc = 0;
for (;;) {
int ca = fgetc(fa), cb = fgetc(fb);
if (ca != cb) { rc = -1; break; }
if (ca == EOF) break;
}
fclose(fa); fclose(fb);
return rc;
}
#define K_RUN 0 /* build+run BOTH drivers, exit==want, + byte-id */
#define K_BUILDERR 1 /* build FAILS with experr on BOTH drivers */
#define K_RUN_CS 2 /* cstage only — ww half pending (cite at row) */
#define K_BUILDERR_CS 3 /* cstage-only loud (ww silent by design) */
struct row { const char *label; const char *src; int want;
int kind; const char *experr; };
/* errlog_has — a BUILDERR row must fail WITH its diagnostic; any other
* failure (parse error, crash, hang-kill) is a vacuous reject (940
* precedent). */
static int
errlog_has(const char *path, const char *needle)
{
FILE *f = fopen(path, "rb");
if (!f) return 0;
char buf[8192];
size_t got = fread(buf, 1, sizeof buf - 1, f);
fclose(f);
buf[got] = '\0';
return strstr(buf, needle) != NULL;
}
static const struct row rows[] = {
{ "binop_alias_base",
"package main;\n"
"type myint = int;\n"
"export fn main() i32 = {\n"
" let a: myint = 5;\n"
" let b: int = 3;\n"
" let c = a + b;\n"
" if (c != 8) { return 1; };\n"
" let d: myint = 2;\n"
" if (a * d != 10) { return 2; };\n"
" if (a < b) { return 3; };\n"
" if (a - b != 2) { return 4; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "binop_2level",
"package main;\n"
"type myint = int;\n"
"type myint2 = myint;\n"
"type myu = u32;\n"
"export fn main() i32 = {\n"
" let a: myint2 = 7;\n"
" let b: int = 2;\n"
" if (a % b != 1) { return 1; };\n"
" let u: myu = 10: u32;\n"
" let v: u32 = 3: u32;\n"
" if (u / v != 3: u32) { return 2; };\n"
" if (u + v != 13: u32) { return 3; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "ret_through_2level",
"package main;\n"
"type myint = int;\n"
"type myint2 = myint;\n"
"fn dbl(x: myint2) int = {\n"
" return x * 2;\n"
"};\n"
"export fn main() i32 = {\n"
" let a: myint2 = 21;\n"
" if (dbl(a) != 42) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "assign_alias_alias",
"package main;\n"
"type k1 = int;\n"
"type k2 = int;\n"
"export fn main() i32 = {\n"
" let x: k1 = 5;\n"
" let y: k2 = x;\n"
" if (y != 5) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
/* harec type_promote: ALIAS+ALIAS → NULL even on a shared base
* (ref/harec/src/check.c:1087-1089). wwstage's checker is silent
* on typed mismatches (5-lite) — cs-only pin. */
{ "binop_alias_vs_alias",
"package main;\n"
"type k1 = int;\n"
"type k2 = int;\n"
"export fn main() i32 = {\n"
" let x: k1 = 5;\n"
" let y: k2 = 3;\n"
" if (x + y != 8) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_BUILDERR_CS, "operands have differing types" },
{ "cond_if",
"package main;\n"
"type myb = bool;\n"
"export fn main() i32 = {\n"
" let b: myb = true;\n"
" if (b) { return 0; };\n"
" return 1;\n"
"};\n", 0, K_RUN, NULL },
{ "cond_for",
"package main;\n"
"type myb = bool;\n"
"export fn main() i32 = {\n"
" let b: myb = true;\n"
" let i: int = 0;\n"
" for (b) {\n"
" i = i + 1;\n"
" if (i >= 3) { b = false; };\n"
" };\n"
" if (i != 3) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "cond_bang",
"package main;\n"
"type myb = bool;\n"
"export fn main() i32 = {\n"
" let b: myb = false;\n"
" let n = !b;\n"
" if (!n) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "cond_andor",
"package main;\n"
"type myb = bool;\n"
"export fn main() i32 = {\n"
" let b: myb = true;\n"
" let c: myb = false;\n"
" if (b && !c) { } else { return 1; };\n"
" if (c || b) { } else { return 2; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "cond_fnparam",
"package main;\n"
"type myb = bool;\n"
"fn pick(b: myb) i32 = {\n"
" if (b) { return 0; };\n"
" return 1;\n"
"};\n"
"export fn main() i32 = {\n"
" let b: myb = true;\n"
" return pick(b);\n"
"};\n", 0, K_RUN, NULL },
{ "assert_stays_loud",
"package main;\n"
"type myb = bool;\n"
"export fn main() i32 = {\n"
" let b: myb = true;\n"
" assert(b);\n"
" return 0;\n"
"};\n", 0, K_BUILDERR, "assert: cond must be bool" },
{ "dot_2level",
"package main;\n"
"type a3 = b3;\n"
"type b3 = c3;\n"
"type c3 = struct { x: size, y: size, z: size };\n"
"export fn main() i32 = {\n"
" if (size(a3) != 24) { return 1; };\n"
" if (size((void | a3)) != 32) { return 2; };\n"
" let v: a3;\n"
" v.x = 1; v.y = 2; v.z = 3;\n"
" if (v.x + v.y + v.z != 6) { return 3; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "deref_alias_ptr",
"package main;\n"
"type pi = *int;\n"
"type pi2 = pi;\n"
"export fn main() i32 = {\n"
" let v: int = 41;\n"
" let p: pi2 = &v;\n"
" if (*p != 41) { return 1; };\n"
" *p = 7;\n"
" if (v != 7) { return 2; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
/* ---- reviewer-F1 find: 2-level alias of slice/str as a STRUCT
* FIELD type. The acceptance above admits every construction; the
* cgen FIELD-TYPE gates single-peeled, so the slice/str 3-word
* arms fell to word0-only scalar tails — SILENT wrong (ww correct,
* every shape LOUD at pristine 738d7f4 = opened by this commit).
* Chased gates: single-dot store (+via-ptr), struct-lit fill,
* chained store-walk leaf, chained-ptr-field store, single-dot /
* via-ptr / chained-walk reads. Each row pins one gate; the
* noise() call clobbers BX/CX so stale-register luck can't pass a
* word0-only header. Unprobed sibling gates are LOUD-tripwired,
* pinned by the #73 row at the end of this block. Rows whose
* `.len` readback rides the chained-dot READ walk entered as
* K_RUN_CS (runtime-correct both stages; cs took the generic
* spine) and graduated to K_RUN with the #71 walk chase. */
{ "slicefield_store_2lvl",
"package main;\n"
"type sl = []int;\n"
"type sl2 = sl;\n"
"type box = struct { s: sl2, n: int };\n"
"export fn main() i32 = {\n"
" let a: [3]int = [700: int, 800: int, 900: int];\n"
" let b: box;\n"
" b.n = 5;\n"
" b.s = a[0:3];\n"
" if (b.n != 5) { return 9; };\n"
" if (b.s[0] != 700) { return 1; };\n"
" if (b.s[2] != 900) { return 2; };\n"
" if (b.s.len != 3) { return 3; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "slicefield_range_2lvl",
"package main;\n"
"type sl = []int;\n"
"type sl2 = sl;\n"
"type box = struct { s: sl2, n: int };\n"
"export fn main() i32 = {\n"
" let a: [3]int = [700: int, 800: int, 900: int];\n"
" let b: box;\n"
" b.s = a[0:3];\n"
" b.n = 5;\n"
" if (b.s.len != 3) { return 1; };\n"
" if (b.s[2] != 900) { return 2; };\n"
" for (let x .. b.s) {\n"
" if (x < 700) { return 3; };\n"
" };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "strfield_store_2lvl",
"package main;\n"
"type s1t = str;\n"
"type s2t = s1t;\n"
"type box = struct { s: s2t, n: int };\n"
"export fn main() i32 = {\n"
" let b: box;\n"
" b.s = \"hello\";\n"
" b.n = 5;\n"
" if (b.s.len != 5) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "slicefield_structlit_2lvl",
"package main;\n"
"type sl = []int;\n"
"type sl2 = sl;\n"
"type box = struct { s: sl2, n: int };\n"
"export fn main() i32 = {\n"
" let a: [3]int = [700: int, 800: int, 900: int];\n"
" let b: box = box { s = a[0:3], n = 5: int };\n"
" if (b.n != 5) { return 1; };\n"
" if (b.s.len != 3) { return 2; };\n"
" if (b.s[2] != 900) { return 3; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "slicefield_viaptr_2lvl",
"package main;\n"
"type sl = []int;\n"
"type sl2 = sl;\n"
"type box = struct { s: sl2, n: int };\n"
"export fn main() i32 = {\n"
" let a: [3]int = [700: int, 800: int, 900: int];\n"
" let b: box;\n"
" let p = &b;\n"
" p.s = a[0:3];\n"
" if (p.s.len != 3) { return 1; };\n"
" if (p.s[2] != 900) { return 2; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "slicefield_chainstore_2lvl",
"package main;\n"
"type sl = []int;\n"
"type sl2 = sl;\n"
"type inner = struct { s: sl2 };\n"
"type outer = struct { i: inner };\n"
"export fn main() i32 = {\n"
" let a: [3]int = [700: int, 800: int, 900: int];\n"
" let v: outer;\n"
" v.i.s = a[0:3];\n"
" if (v.i.s.len != 3) { return 1; };\n"
" if (v.i.s[2] != 900) { return 2; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "slicefield_ptrchain_2lvl",
"package main;\n"
"type sl = []int;\n"
"type sl2 = sl;\n"
"type inner = struct { s: sl2, n: int };\n"
"type outer = struct { pi: *inner };\n"
"export fn main() i32 = {\n"
" let a: [3]int = [700: int, 800: int, 900: int];\n"
" let i: inner;\n"
" i.n = 1;\n"
" let v: outer;\n"
" v.pi = &i;\n"
" v.pi.s = a[0:3];\n"
" if (i.s.len != 3) { return 1; };\n"
" if (i.s[2] != 900) { return 2; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "slicefield_chainread_2lvl",
"package main;\n"
"type sl = []int;\n"
"type sl2 = sl;\n"
"type inner = struct { s: sl2 };\n"
"type outer = struct { i: inner };\n"
"fn noise(x: int) int = {\n"
" return x * 7 + 3;\n"
"};\n"
"export fn main() i32 = {\n"
" let a: [3]int = [700: int, 800: int, 900: int];\n"
" let v: outer;\n"
" v.i.s = a[0:3];\n"
" let k = noise(9);\n"
" if (k != 66) { return 9; };\n"
" let w = v.i.s;\n"
" if (w.len != 3) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "slicefield_ptrread_2lvl",
"package main;\n"
"type sl = []int;\n"
"type sl2 = sl;\n"
"type box = struct { s: sl2, n: int };\n"
"fn noise(x: int) int = {\n"
" return x * 7 + 3;\n"
"};\n"
"export fn main() i32 = {\n"
" let a: [3]int = [700: int, 800: int, 900: int];\n"
" let b: box;\n"
" b.s = a[0:3];\n"
" let p = &b;\n"
" let k = noise(9);\n"
" if (k != 66) { return 9; };\n"
" let w = p.s;\n"
" if (w.len != 3) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
/* whole-field read into a local: cs runtime-correct post-chase
* (the clobbered-register r1b probe). The `let w = b.s` receive
* spine divergence noted at pristine 738d7f4 no longer
* reproduces at the F1-merged base, and ww's `w[i]` read (the
* task-#60 esz half) landed in F2a batch 1 — byte-id + 0/0
* verified, graduated K_RUN. */
{ "slicefield_wholeread_2lvl",
"package main;\n"
"type sl = []int;\n"
"type sl2 = sl;\n"
"type box = struct { s: sl2, n: int };\n"
"fn noise(x: int) int = {\n"
" return x * 7 + 3;\n"
"};\n"
"export fn main() i32 = {\n"
" let a: [3]int = [700: int, 800: int, 900: int];\n"
" let b: box;\n"
" b.s = a[0:3];\n"
" let k = noise(9);\n"
" if (k != 66) { return 9; };\n"
" let w = b.s;\n"
" if (w.len != 3) { return 1; };\n"
" if (w[2] != 900) { return 2; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL }, /* graduated: #60 (F2a batch 1) */
/* #73 tripwire pin: the UNPROBED single-peel field gates
* (indexed-elem store/read, ptr-chain read, heap fill, tuple-elem
* read, static emit) hard-error on a 2+-level alias over an
* aggregate base instead of emitting a word0 tail. ww accepts and
* runs these — cs-only loud until #73's chase. 1-level controls
* verified per gate (/tmp/revF1 t*c probes). */
{ "slicefield_idx_tripwire_73",
"package main;\n"
"type sl = []int;\n"
"type sl2 = sl;\n"
"type box = struct { s: sl2, n: int };\n"
"export fn main() i32 = {\n"
" let a: [3]int = [700: int, 800: int, 900: int];\n"
" let xs: [2]box;\n"
" xs[0].s = a[0:3];\n"
" if (xs[0].s.len != 3) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_BUILDERR_CS,
"unswept single-peel gate (#73)" },
/* Values >255 break the esz=1 prefix-luck; the write-then-read
* pins the IMULQ stride on both the read and write spines. */
{ "idx_2level",
"package main;\n"
"type arr = [4]int;\n"
"type arr2 = arr;\n"
"export fn main() i32 = {\n"
" let a: arr2 = [1000: int, 2000: int, 3000: int, 4000: int];\n"
" if (a[2] != 3000) { return 1; };\n"
" a[1] = 9999;\n"
" if (a[1] != 9999) { return 2; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL }, /* graduated: #60 (F2a batch 1) */
{ "slice_2level",
"package main;\n"
"type sl = []int;\n"
"type sl2 = sl;\n"
"export fn main() i32 = {\n"
" let a: [4]int = [1000: int, 2000: int, 3000: int, 4000: int];\n"
" let s: sl2 = a[1:3];\n"
" if (s.len != 2) { return 1; };\n"
" if (s[0] != 2000) { return 2; };\n"
" s[1] = 7777;\n"
" if (a[2] != 7777) { return 3; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL }, /* graduated: #60 (F2a batch 1) */
{ "range_2level",
"package main;\n"
"type arr = [4]int;\n"
"type arr2 = arr;\n"
"export fn main() i32 = {\n"
" let a: arr2 = [1: int, 2: int, 3: int, 4: int];\n"
" let sum: int = 0;\n"
" for (let x .. a) {\n"
" sum = sum + x;\n"
" };\n"
" if (sum != 10) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL }, /* graduated: #60 (F2a batch 1) */
{ "slice_of_alias_arg",
"package main;\n"
"type arr = [4]int;\n"
"type arr2 = arr;\n"
"fn sum(s: []int) int = {\n"
" let t: int = 0;\n"
" for (let x .. s) { t = t + x; };\n"
" return t;\n"
"};\n"
"export fn main() i32 = {\n"
" let a: arr2 = [1000: int, 2000: int, 3000: int, 4000: int];\n"
" let s = a[1:3];\n"
" if (s.len != 2) { return 1; };\n"
" if (s[1] != 3000) { return 2; };\n"
" if (sum(a[0:4]) != 10000) { return 3; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL }, /* graduated: #60 (F2a batch 1) */
/* ---- ken-v3 leg: the acceptance align above opens 2-level
* float/str/slice aliases to the cgen KIND classifiers
* (cg_isfloat/type_isf32/fld_isfloat/type_isstr/type_isslice),
* whose single peel classed them scalar/INT — the f64-alias param
* would read the wrong register class (cs exit 1 SILENT, ww
* correct). The classifiers chase IN THIS SAME COMMIT so the
* widening never ships a loud->silent flip (rule 7; ken root-
* verify /tmp/ken_f1, his v3 row below). */
{ "float_alias_param_kenv3",
"package main;\n"
"type fa = fb;\n"
"type fb = f64;\n"
"fn take(x: fa) f64 = {\n"
" return x * 2.0;\n"
"};\n"
"export fn main() i32 = {\n"
" if (take(1.5) != 3.0) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "float_alias_param",
"package main;\n"
"type f1t = f64;\n"
"type f2t = f1t;\n"
"fn half(x: f2t) f64 = {\n"
" return x / 2.0;\n"
"};\n"
"export fn main() i32 = {\n"
" let v: f2t = 5.0;\n"
" if (half(v) != 2.5) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "str_alias_2level",
"package main;\n"
"type s1t = str;\n"
"type s2t = s1t;\n"
"fn taillen(s: s2t) int = {\n"
" return (s.len: int);\n"
"};\n"
"export fn main() i32 = {\n"
" let v: s2t = \"hello\";\n"
" if (v.len != 5) { return 1; };\n"
" if (taillen(v) != 5) { return 2; };\n"
" let w: s2t = v;\n"
" if (w.len != 5) { return 3; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
/* slice leg: cs classify fixed; the ww half of the indexed read
* (task-#60 esz family) landed in F2a batch 1. Values >255
* break the esz=1 prefix-luck. */
{ "slice_alias_param",
"package main;\n"
"type b1 = []int;\n"
"type b2 = b1;\n"
"fn first(s: b2) int = {\n"
" return s[0];\n"
"};\n"
"export fn main() i32 = {\n"
" let a: [3]int = [1000: int, 2000: int, 3000: int];\n"
" let s: b2 = a[0:3];\n"
" if (first(s) != 1000) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL }, /* graduated: #60 (F2a batch 1) */
/* ---- task #61: cstage alias-NAMED struct PARAM classify.
* The single peel classified a 2-level-alias param SCALAR: caller
* pushed and callee spilled ONE eightbyte, fields read saved-BP/
* return-address garbage (F0 m5_arg/m8b_arg1lit, cs exit 1 SILENT,
* ww correct). Fix = struct_arg_size/aggarg_size/struct_float_
* class + the prologue classify chase. Values are distinct and the
* LAST field is always checked (multi-eightbyte exit-checked). */
{ "arg_2level_fwdref",
"package main;\n"
"type ali = base;\n"
"type base = struct { a: size, b: size, c: size };\n"
"fn take(s: ali) size = {\n"
" return s.a + s.b + s.c;\n"
"};\n"
"export fn main() i32 = {\n"
" let x: ali;\n"
" x.a = 4; x.b = 9; x.c = 13;\n"
" if (take(x) != 26) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "arg_2level_litinit",
"package main;\n"
"type st = struct { a: size, b: size, c: size };\n"
"type row = st;\n"
"fn take(s: row) size = {\n"
" return s.a + s.b + s.c;\n"
"};\n"
"export fn main() i32 = {\n"
" let x: st = st { a = 4: size, b = 9: size, c = 13: size };\n"
" if (take(x) != 26) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
/* 40B struct: 5 GP eightbytes through the aggarg (>16B) leg. */
{ "arg_2level_5word",
"package main;\n"
"type big = struct { a: size, b: size, c: size, d: size, e: size };\n"
"type big2 = big;\n"
"fn take(s: big2) size = {\n"
" return s.a + s.e;\n"
"};\n"
"export fn main() i32 = {\n"
" let v: big2;\n"
" v.a = 1000; v.b = 2; v.c = 3; v.d = 4; v.e = 5000;\n"
" if (take(v) != 6000) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
/* f64-bearing 16B struct: the struct_float_class SSE leg. */
{ "arg_2level_floatclass",
"package main;\n"
"type fs = struct { x: f64, n: size };\n"
"type fs2 = fs;\n"
"fn take(s: fs2) size = {\n"
" if (s.x != 2.5) { return 99; };\n"
" return s.n;\n"
"};\n"
"export fn main() i32 = {\n"
" let v: fs2;\n"
" v.x = 2.5; v.n = 7;\n"
" if (take(v) != 7) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
/* control: base-named param spelling stays green + byte-id. */
{ "arg_base_control",
"package main;\n"
"type base = struct { a: size, b: size, c: size };\n"
"fn take(s: base) size = {\n"
" return s.a + s.b + s.c;\n"
"};\n"
"export fn main() i32 = {\n"
" let x: base;\n"
" x.a = 4; x.b = 9; x.c = 13;\n"
" if (take(x) != 26) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
/* ---- task #62 Layer-2: alias-NAMED struct as a UNION MEMBER.
* The widen store/push source classify fell past the struct arm
* to the scalar arm — word0-only payload (the banked rows
* /tmp/impl62r_layer2_rows.md; both-wrong-identical at normal
* decl order = gate-blind byte-id). cs half c138605
* (cg_widen_tagged_store/push su chase); ww half F2a batch-2 c2
* (rhsstructpayload -> structlookupchain) — K_RUN, byte-id.
* Values distinct per word; the LAST payload word is always
* checked. The RETURN-position leg stays both-stage divergent —
* cs cgreturn residual, task #89 (ww runtime-correct since c2;
* not pinned here until the cs half lands). */
{ "union_store_norm", /* banked row L2-1 (= F0 m5b_match1) */
"package main;\n"
"type base = struct { a: size, b: size };\n"
"type ali = base;\n"
"export fn main() i32 = {\n"
" let x: ali;\n"
" x.a = 4; x.b = 9;\n"
" let v: (void | ali) = x;\n"
" match (v) {\n"
" case let s: ali => {\n"
" if (s.a != 4) { return 1; };\n"
" if (s.b != 9) { return 2; };\n"
" };\n"
" case void => { return 3; };\n"
" };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "union_store_fwd", /* banked row L2-2 (= F0 m5_match) */
"package main;\n"
"type ali = base;\n"
"type base = struct { a: size, b: size };\n"
"export fn main() i32 = {\n"
" let x: ali;\n"
" x.a = 4; x.b = 9;\n"
" let v: (void | ali) = x;\n"
" match (v) {\n"
" case let s: ali => {\n"
" if (s.a != 4) { return 1; };\n"
" if (s.b != 9) { return 2; };\n"
" };\n"
" case void => { return 3; };\n"
" };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "union_store_3word", /* banked row L2-4: pins the width LOOP */
"package main;\n"
"type base = struct { a: size, b: size, c: size };\n"
"type ali = base;\n"
"export fn main() i32 = {\n"
" let x: ali;\n"
" x.a = 4; x.b = 9; x.c = 3;\n"
" let v: (void | ali) = x;\n"
" match (v) {\n"
" case let s: ali => {\n"
" if (s.a != 4) { return 1; };\n"
" if (s.c != 3) { return 2; };\n"
" };\n"
" case void => { return 3; };\n"
" };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "union_push_arg", /* the cg_widen_tagged_push twin (F1 find) */
"package main;\n"
"type base = struct { a: size, b: size };\n"
"type ali = base;\n"
"fn peek(v: (void | ali)) size = {\n"
" match (v) {\n"
" case let s: ali => { return s.b; };\n"
" case void => { return 0; };\n"
" };\n"
"};\n"
"export fn main() i32 = {\n"
" let x: ali;\n"
" x.a = 4; x.b = 9;\n"
" if (peek(x) != 9) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
/* banked row L2-5: the m5b_match0 gold invariant — base spelling
* indistinguishable (ken oracle PART 1.7). */
{ "union_store_base_ctl",
"package main;\n"
"type base = struct { a: size, b: size, c: size };\n"
"export fn main() i32 = {\n"
" let x: base;\n"
" x.a = 4; x.b = 9; x.c = 3;\n"
" let v: (void | base) = x;\n"
" match (v) {\n"
" case let s: base => {\n"
" if (s.a != 4) { return 1; };\n"
" if (s.c != 3) { return 2; };\n"
" };\n"
" case void => { return 3; };\n"
" };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
/* ---- F2a batch-3 c3 (task #92, reviewer-B2 find): the same
* rhsstructpayload widen, sourced from a struct LITERAL instead
* of a local ident — the N_STRUCTLIT arm still did bare
* structlookup, so `ali{...}` into a union fell to the scalar
* widen arm (cs 0 / ww EXIT 1, byte-id NO, pre-existing on
* master at 486f7f8). Graduated by routing the arm through
* structlookupchain (entry gate widened to the literal's N_IDENT
* type-ref leaf — consumer census in the commit body). Values
* distinct per word, LAST word checked. The alias struct-LIT
* LET-INIT zero-fill (task #63) does NOT green at this site —
* probed post-c3, documented there, deliberately no row here. */
{ "union_slit_base_ctl",
"package main;\n"
"type base = struct { a: size, b: size };\n"
"export fn main() i32 = {\n"
" let v: (void | base) = base{a=4000, b=9000};\n"
" match (v) {\n"
" case let s: base => {\n"
" if (s.a != 4000) { return 1; };\n"
" if (s.b != 9000) { return 2; };\n"
" };\n"
" case void => { return 3; };\n"
" };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "union_slit_alias",
"package main;\n"
"type base = struct { a: size, b: size };\n"
"type ali = base;\n"
"export fn main() i32 = {\n"
" let v: (void | ali) = ali{a=4000, b=9000};\n"
" match (v) {\n"
" case let s: ali => {\n"
" if (s.a != 4000) { return 1; };\n"
" if (s.b != 9000) { return 2; };\n"
" };\n"
" case void => { return 3; };\n"
" };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
/* 2-level: the chain walk (structlookupchain's alias loop). */
{ "union_slit_alias2",
"package main;\n"
"type base = struct { a: size, b: size };\n"
"type ali = base;\n"
"type ali2 = ali;\n"
"export fn main() i32 = {\n"
" let v: (void | ali2) = ali2{a=4000, b=9000};\n"
" match (v) {\n"
" case let s: ali2 => {\n"
" if (s.a != 4000) { return 1; };\n"
" if (s.b != 9000) { return 2; };\n"
" };\n"
" case void => { return 3; };\n"
" };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "union_slit_order",
"package main;\n"
"export fn main() i32 = {\n"
" let v: (void | ali) = ali{a=4000, b=9000};\n"
" match (v) {\n"
" case let s: ali => {\n"
" if (s.a != 4000) { return 1; };\n"
" if (s.b != 9000) { return 2; };\n"
" };\n"
" case void => { return 3; };\n"
" };\n"
" return 0;\n"
"};\n"
"type ali = base;\n"
"type base = struct { a: size, b: size };\n", 0, K_RUN, NULL },
/* ---- F2a batch-2 c3/B1: exprprimresolved's N_DOT base walk was
* a hand-rolled 2-peel — a 3-level alias base (or ptr-to-2-level)
* left the cast-source width unknowable on wwstage only, so the
* #33 identity clamp stayed emitted where cstage (castsrcprim,
* F1-chased) skipped it: runtime-correct both, byte-id NO.
* Graduated by the tichase walk; 1/2-level controls held all
* along (the 2-peel covered them by accident). */
{ "castprim_3lvl_base",
"package main;\n"
"type s1 = struct { f: u32 };\n"
"type s2 = s1;\n"
"type s3 = s2;\n"
"export fn main() i32 = {\n"
" let x: s3;\n"
" x.f = 70000;\n"
" let y: u64 = (x.f: u32): u64;\n"
" if (y != 70000) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "castprim_ptr2lvl_base",
"package main;\n"
"type s1 = struct { f: u32 };\n"
"type s2 = s1;\n"
"export fn main() i32 = {\n"
" let x: s2;\n"
" x.f = 70000;\n"
" let p: *s2 = &x;\n"
" let y: u64 = (p.f: u32): u64;\n"
" if (y != 70000) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
/* 2-level control (was already byte-id pre-c3; pins the accident
* out of existence). */
{ "castprim_2lvl_base_ctl",
"package main;\n"
"type s1 = struct { f: u32 };\n"
"type s2 = s1;\n"
"export fn main() i32 = {\n"
" let x: s2;\n"
" x.f = 70000;\n"
" let y: u64 = (x.f: u32): u64;\n"
" if (y != 70000) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
/* ---- F2a batch-2 c4 (rob FINAL RULING (i)): tyassignableuntyped
* full-chase — STRUCTURAL alignment to cs type.c:369-385 / harec
* type_is_assignable; ZERO acceptance graduations in this commit
* (graduations ride task #90). Holds + controls pin the chase as
* behavior-neutral on every reachable shape; the tagged-dst rows
* are the #33 pins (drill semantics unchanged). */
{ "untyped_hold33_pin", /* (void|T) untyped-int init — #33 fixed
* behavior, tagged-dst drill HOLD */
"package main;\n"
"export fn main() i32 = {\n"
" let mn: (void | size) = 5;\n"
" if (!(mn is size)) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "untyped_tagdst_2lvl_hold", /* 2-level alias TAGGED dst holds */
"package main;\n"
"type r1 = (void | size);\n"
"type r2 = r1;\n"
"export fn main() i32 = {\n"
" let v: r2 = 5;\n"
" if (!(v is size)) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "untyped_str2lvl_ctl", /* masked twin: ww stamps the str
* literal CONCRETE (#14 cluster), the
* shape fallback rescues the tag — 0/0
* all along; documents the rescue */
"package main;\n"
"type sa1 = str;\n"
"type sa2 = sa1;\n"
"export fn main() i32 = {\n"
" let v: (void | sa2) = \"hi\";\n"
" if (!(v is sa2)) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "untyped_int2lvl_ctl", /* typeisnum NAMED-recursion control */
"package main;\n"
"type ia1 = i64;\n"
"type ia2 = ia1;\n"
"export fn main() i32 = {\n"
" let v: (void | ia2) = 7;\n"
" if (!(v is ia2)) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "untyped_bool1lvl_ctl", /* 1 level: ww passes via the
* fallback's one peel — 0/0 observed */
"package main;\n"
"type ba1 = bool;\n"
"export fn main() i32 = {\n"
" let v: (void | ba1) = true;\n"
" if (!(v is ba1)) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
/* BOUND row (task #90): ww stamps N_TRUE CONCRETE bool
* (check.ww:2440) vs cs untyped_bool (check.c:1234), so the bool
* literal never reaches the c4-chased untyped funnel on ww — it
* dies at flatvariantidxt pass-2's one-level pu.under guard
* (cgenutil.ww:2868, the #17 site): SILENT tag 0, ww runs exit 1
* where cs runs 0. Flip to K_RUN when #90 clears BOTH layers
* (stamp + fallback peel). */
{ "untyped_bool2lvl_bound90",
"package main;\n"
"type bb1 = bool;\n"
"type bb2 = bb1;\n"
"export fn main() i32 = {\n"
" let v: (void | bb2) = true;\n"
" if (!(v is bb2)) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_RUN_CS, NULL }, /* ww: task #90 */
/* BOUND expected-state row (#199α + #90): untyped literal into a
* NESTED-tagged alias-wrapped variant. cs CHECKER loud-rejects —
* the #199α ww-stricter no-transitive-drill rule (type.c:316-324);
* ww's node-keyed checker ACCEPTS and the binary runs exit 0
* (observed post-c4; the harness has no cs-reject+ww-runs mode,
* so the ww half is pinned via #90's metadata, not here). The c4
* pu-chase aligned the CGEN drill structure to cs; the acceptance
* gate is check.ww — batch-4 aligns ww down, then this row flips
* to K_BUILDERR (loud BOTH). */
{ "untyped_nestvar_bound",
"package main;\n"
"type inner = (i64 | str);\n"
"type inner2 = inner;\n"
"export fn main() i32 = {\n"
" let v: (void | inner2) = 7;\n"
" if (v is void) { return 1; };\n"
" return 0;\n"
"};\n", 0, K_BUILDERR_CS, "not assignable" },
/* ---- task #71 (rob probe-ruled F1 enrollment): nested fields
* whose TYPES are aliases. The chained-dot store/read/addr-of
* walks single-peeled each hop, aborted on the alias, and fell
* to the generic PUSHQ/LEAQ/ADDQ/POPQ address spine — runtime-
* correct but byte-id NO vs wwstage's folded direct offsets.
* Chasing the walks converges cs onto the direct arm = ww's asm.
* Distinct values; the LAST field of the SECOND member checked. */
{ "nested_alias_field_norm",
"package main;\n"
"type fa = inner;\n"
"type inner = struct { a: size, b: size };\n"
"type outer = struct { x: fa, y: fa };\n"
"export fn main() i32 = {\n"
" let v: outer;\n"
" v.x.a = 4; v.x.b = 9;\n"
" v.y.a = 7; v.y.b = 3;\n"
" if (v.x.b != 9) { return 1; };\n"
" if (v.y.b != 3) { return 2; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
{ "nested_alias_field_fwd",
"package main;\n"
"type outer = struct { x: fa, y: fa };\n"
"type fa = inner;\n"
"type inner = struct { a: size, b: size };\n"
"export fn main() i32 = {\n"
" let v: outer;\n"
" v.x.a = 4; v.x.b = 9;\n"
" v.y.a = 7; v.y.b = 3;\n"
" if (v.x.b != 9) { return 1; };\n"
" if (v.y.b != 3) { return 2; };\n"
" let pa = &v.y.b;\n"
" *pa = 11;\n"
" if (v.y.b != 11) { return 3; };\n"
" return 0;\n"
"};\n", 0, K_RUN, NULL },
/* banked row L2-3 (`v as ali` readback) trips task #54's as-binding
* aggregate-init bound — LOUD both stages today; fold the row into
* #54's pin set on its fold (do not drop). Pinned here as the
* loud-both bound so a silent regression can't hide. */
{ "union_as_bound_54",
"package main;\n"
"type base = struct { a: size, b: size };\n"
"type ali = base;\n"
"export fn main() i32 = {\n"
" let x: ali;\n"
" x.a = 4; x.b = 9;\n"
" let v: (void | ali) = x;\n"
" if (!(v is ali)) { return 1; };\n"
" let w = v as ali;\n"
" if (w.b != 9) { return 2; };\n"
" return 0;\n"
"};\n", 0, K_BUILDERR,
"aggregate init from unhandled rhs shape" },
};
static int
run_driver(const char *driver, const struct row *r, int i)
{
char src[96], tmpdir[96], errf[96], cmd[1024];
snprintf(src, sizeof src, "/tmp/aac_%d_%d.ww", getpid(), i);
snprintf(tmpdir, sizeof tmpdir, "/tmp/aac_%d_d_%d", getpid(), i);
snprintf(errf, sizeof errf, "/tmp/aac_%d_e_%d", getpid(), i);
FILE *f = fopen(src, "wb");
if (!f) return -1;
fputs(r->src, f);
fclose(f);
mkdir(tmpdir, 0755);
snprintf(cmd, sizeof cmd,
"cd %s && timeout 20 %s build %s >/dev/null 2>%s",
tmpdir, driver, src, errf);
int brc = runwait(cmd);
if (r->kind == K_BUILDERR || r->kind == K_BUILDERR_CS) {
int ok = (brc != 0)
&& (r->experr == NULL || errlog_has(errf, r->experr));
if (!ok)
fprintf(stderr, "row[%s]: %s expected loud builderr "
"\"%s\" (brc=%d)\n", r->label, driver,
r->experr ? r->experr : "", brc);
unlink(src); unlink(errf); rmdir(tmpdir);
return ok ? 0 : 1;
}
if (brc != 0) {
fprintf(stderr, "row[%s]: build via %s failed\n",
r->label, driver);
unlink(src); unlink(errf); rmdir(tmpdir);
return -1;
}
const char *base = strrchr(src, '/');
base = base ? base + 1 : src;
char outbin[256];
snprintf(outbin, sizeof outbin, "%s/%s", tmpdir, base);
char *dot = strrchr(outbin, '.');
if (dot && strcmp(dot, ".ww") == 0) *dot = '\0';
int got = runwait(outbin);
unlink(src); unlink(outbin); unlink(errf); rmdir(tmpdir);
if (got != r->want) {
fprintf(stderr, "row[%s]: %s exit %d, want %d\n",
r->label, driver, got, r->want);
return 1;
}
return 0;
}
static int
asm_byte_identical(const char *bin, const struct row *r, int i)
{
char src[96], cs[96], ws[96], cmd[1024];
snprintf(src, sizeof src, "/tmp/aac_asm_%d_%d.ww", getpid(), i);
snprintf(cs, sizeof cs, "/tmp/aac_asm_%d_%d_c.s", getpid(), i);
snprintf(ws, sizeof ws, "/tmp/aac_asm_%d_%d_w.s", getpid(), i);
FILE *f = fopen(src, "wb");
if (!f) return -1;
fputs(r->src, f);
fclose(f);
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s 2>/dev/null", bin, cs, src);
if (runwait(cmd) != 0) {
fprintf(stderr, "row[%s]: w6c errored\n", r->label);
unlink(src);
return -1;
}
snprintf(cmd, sizeof cmd, "%s/w6c_ww -o %s %s 2>/dev/null",
bin, ws, src);
if (runwait(cmd) != 0) {
fprintf(stderr, "row[%s]: w6c_ww errored\n", r->label);
unlink(src); unlink(cs);
return -1;
}
int rc = slurp_eq(cs, ws);
if (rc != 0)
fprintf(stderr, "row[%s]: cstage vs wwstage asm differs\n",
r->label);
unlink(src); unlink(cs); unlink(ws);
return rc;
}
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 n = (int)(sizeof rows / sizeof rows[0]);
int total = 0, fail = 0;
for (int i = 0; i < n; i++) {
total++;
if (run_driver(cdrv, &rows[i], i) != 0) fail++;
}
if (access(wdrv, X_OK) == 0) {
for (int i = 0; i < n; i++) {
if (rows[i].kind == K_RUN_CS
|| rows[i].kind == K_BUILDERR_CS)
continue;
total++;
if (run_driver(wdrv, &rows[i], i) != 0) fail++;
}
for (int i = 0; i < n; i++) {
if (rows[i].kind != K_RUN)
continue;
total++;
if (asm_byte_identical(bin, &rows[i], i) != 0) fail++;
}
}
if (fail) {
fprintf(stderr, "alias_accept: %d/%d checks failed\n",
fail, total);
return 1;
}
printf("alias_accept: %d/%d ok\n", total, total);
return 0;
}