cgen: B6-c1 assign/reassign family single peels fold into type_chase_named — 9 lines, cs-only
The exact B6-c1 set (rob b6 spec §2): cgexpr :6359 (tagged-local plain
reassign lu), :6403/:6405 (deref-target assign pu/vt), :6460/:6462
(deref compound-assign pu/vt), :6518 (str/slice/struct reassign lu) +
cgstmt :11696 (nomem null-propagate r), :12047 (assign base peel bu),
:13625 (destructure-reassign rhs ru — chased; the #64 citation above it
stays, the deferral is about the tuple-literal rhs ROUTE, not this
peel). Raw `->under` in cgen.c 58→49.
TRAIN INVARIANT: cs-only — zero selfhost/ or lib/ bytes move; w6c_ww/
ww_ww bit-identical to ken's 4cac1cb baselines (md5
b6bddc8eb5c3ed8e805e50371d4b7017 / 4e9ca8741f19e1f68219ff799a5e5a14).
cs movers bounded to exactly: kb6_streassign, kb5_wstore_a (the
named c1 family); the rest of the kb4/kb5/kb6/kna corpus + five
selfhost mains byte-NEUTRAL both stages; kw1_101 / fill2 / tuparg_c /
xampdef / amplen1 detectors unmoved. 989 lib ratchet: zero flips.
LIVE graduation: kb6_streassign (the :6518 lu single-peel missed
TY_STR at 2 alias levels, fell to the scalar default — `b = a` copied
the ptr WORD0 only, len/cap stale, cs silent exit 1; ww was the
runtime-correct full 3-word reference) → 0/0 byte-id. Designed
graduation: kb5_wstore_a (ken C1-CORR-2 seed — the ident-lhs N_ASSIGN
tagged gate :6359 is cgexpr INLINE, never reached B5's :2456 funnel)
→ wstore_a_2lvl re-pinned K_RUN_NOID→K_RUN in the b5 suite (84→85
checks). kb6_sreassign / kb6_dassign latent controls byte-NEUTRAL as
ken's structural bound predicts.
New 944_alias_cgen_b6_run row table (3 rows, 9 checks): streassign_2lvl
+ sreassign_2lvl/dassign_2lvl controls; Makefile wires
test_alias_cgen_b6_run into the unit list. All 944-family suites green;
sizelint 0.
This commit is contained in:
7
Makefile
7
Makefile
@@ -309,6 +309,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
|
||||
$(BIN)/test_alias_def_addr_run \
|
||||
$(BIN)/test_alias_global_decl_run \
|
||||
$(BIN)/test_alias_cgen_b5_run \
|
||||
$(BIN)/test_alias_cgen_b6_run \
|
||||
$(BIN)/test_tuple_nary_destructure_run \
|
||||
$(BIN)/test_rvalue_tuple_destructure_run \
|
||||
$(BIN)/test_overcap_tuple_field_store_run \
|
||||
@@ -1495,6 +1496,12 @@ $(BIN)/test_alias_cgen_b5_run: test/wcc/944_alias_cgen_b5_run.c \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BIN)/test_alias_cgen_b6_run: test/wcc/944_alias_cgen_b6_run.c \
|
||||
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
||||
$(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BIN)/test_tuple_nary_destructure_run: test/wcc/945_tuple_nary_destructure_run.c \
|
||||
$(BIN)/ww $(BIN)/w6c $(BIN)/w6a $(BIN)/w6l \
|
||||
$(BIN)/ww_ww $(BIN)/w6c_ww $(BIN)/w6a_ww $(BIN)/w6l_ww \
|
||||
|
||||
@@ -6356,7 +6356,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
if (n->lhs && n->lhs->kind == N_IDENT && n->op == TK_ASSIGN
|
||||
&& n->lhs->type) {
|
||||
Type *lt = n->lhs->type;
|
||||
Type *lu = (lt && lt->kind == TY_NAMED) ? lt->under : lt;
|
||||
Type *lu = type_chase_named(lt);
|
||||
if (lu && lu->kind == TY_TAGGED) {
|
||||
int rhs_sret_call = n->rhs
|
||||
&& n->rhs->kind == N_CALL
|
||||
@@ -6400,9 +6400,9 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
if (n->lhs && n->lhs->kind == N_UN && n->lhs->op == TK_STAR
|
||||
&& n->op == TK_ASSIGN && !place_slit && !deref_agg) {
|
||||
Type *pt = n->lhs->lhs ? n->lhs->lhs->type : NULL;
|
||||
Type *pu = (pt && pt->kind == TY_NAMED) ? pt->under : pt;
|
||||
Type *pu = type_chase_named(pt);
|
||||
Type *vt = (pu && pu->kind == TY_PTR) ? pu->sub : NULL;
|
||||
if (vt && vt->kind == TY_NAMED) vt = vt->under;
|
||||
vt = type_chase_named(vt);
|
||||
/* `*p = v` for *f64 / *f32: cgexpr leaves the value in X0,
|
||||
* not AX. Spill X0 to the stack, evaluate the pointer
|
||||
* (clobbers AX/BX freely), then reload X0 and MOVSD/MOVSS
|
||||
@@ -6457,9 +6457,9 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
if (n->lhs && n->lhs->kind == N_UN && n->lhs->op == TK_STAR
|
||||
&& n->op != TK_ASSIGN) {
|
||||
Type *pt = n->lhs->lhs ? n->lhs->lhs->type : NULL;
|
||||
Type *pu = (pt && pt->kind == TY_NAMED) ? pt->under : pt;
|
||||
Type *pu = type_chase_named(pt);
|
||||
Type *vt = (pu && pu->kind == TY_PTR) ? pu->sub : NULL;
|
||||
if (vt && vt->kind == TY_NAMED) vt = vt->under;
|
||||
vt = type_chase_named(vt);
|
||||
int sz = vt ? (int)vt->size : 8;
|
||||
int load_op = fldloadop(vt, sz);
|
||||
int store_op = fldstoreop(vt, sz);
|
||||
@@ -6515,7 +6515,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
if (n->lhs && n->lhs->kind == N_IDENT && n->op == TK_ASSIGN
|
||||
&& n->lhs->type) {
|
||||
Type *lt = n->lhs->type;
|
||||
Type *lu = (lt && lt->kind == TY_NAMED) ? lt->under : lt;
|
||||
Type *lu = type_chase_named(lt);
|
||||
/* str/slice local/let: str IS []u8, so both store the full
|
||||
* 3-word {ptr,len,cap} from (AX,BX,CX) at off+0/+8/+16
|
||||
* (local) or via &name(SB) → DI scratch (global — CX holds
|
||||
@@ -11693,7 +11693,7 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
||||
ins2(c, A_CMPQ, aimm(0), areg(D_AX));
|
||||
ins1(c, A_JNE, abranch(ok));
|
||||
Type *r = cg_ret_type;
|
||||
if (r && r->kind == TY_NAMED) r = r->under;
|
||||
r = type_chase_named(r);
|
||||
int nidx = cg_tag_for_variant(r, ty_nomem);
|
||||
if (nidx < 0) nidx = 1;
|
||||
ins2(c, A_MOVQ, aimm(nidx), areg(D_AX));
|
||||
@@ -12043,8 +12043,7 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
||||
Node *base = n->rhs->lhs;
|
||||
Node *idx = n->rhs->rhs;
|
||||
Type *bt = base ? base->type : NULL;
|
||||
Type *bu = (bt && bt->kind == TY_NAMED)
|
||||
? bt->under : bt;
|
||||
Type *bu = type_chase_named(bt);
|
||||
if (base && base->kind == N_IDENT && bu
|
||||
&& bu->kind == TY_ARRAY) {
|
||||
int esz = (bu->sub)
|
||||
@@ -13622,7 +13621,7 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
||||
* (silent skew) — the #57 decl wire stops at return/let. */
|
||||
cgexpr(c, n->rhs, *locals);
|
||||
Type *rt = n->rhs ? n->rhs->type : NULL;
|
||||
Type *ru = (rt && rt->kind == TY_NAMED) ? rt->under : rt;
|
||||
Type *ru = type_chase_named(rt);
|
||||
Tparam *tp0 = (ru && ru->kind == TY_TUPLE) ? ru->params : NULL;
|
||||
int mf32;
|
||||
if (sret_recv > 0) {
|
||||
|
||||
@@ -26,12 +26,11 @@
|
||||
* wstore_2lvl/_1lvl | kb5_wstore/wstore1: let-route |
|
||||
* | controls (du arrives chased |
|
||||
* | upstream — ken FLAG-1), NEUTRAL | 0/0
|
||||
* wstore_a_bound_b6 | kb5_wstore_a: ASSIGN-route re-store |
|
||||
* | — both-correct divergent; the |
|
||||
* | ident-lhs N_ASSIGN gates in the |
|
||||
* | cgexpr INLINE set (B6), NOT the |
|
||||
* | :2456 funnel (C1-CORR-2, corrects |
|
||||
* | rob R2) — byte-id waived until B6 | 0/0
|
||||
* wstore_a_2lvl | kb5_wstore_a: ASSIGN-route re-store |
|
||||
* | — was both-correct divergent; the |
|
||||
* | ident-lhs N_ASSIGN gate (:6359) is |
|
||||
* | cgexpr INLINE, NOT the :2456 funnel |
|
||||
* | (C1-CORR-2) — GRADUATED at B6-c1 | 0/0
|
||||
* succ_2lvl | kb5_succ: `?`-success remap over |
|
||||
* | 2-lvl alias result — was divergent |
|
||||
* | at RETURN positions only (C1-CORR-1)|
|
||||
@@ -269,12 +268,11 @@ static const struct row rows[] = {
|
||||
" };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, 0, K_RUN, NULL },
|
||||
/* C1-CORR-2 (ken c1-boundary addendum): the assign-route
|
||||
* divergence does NOT close in this train — the ident-lhs
|
||||
* N_ASSIGN tagged store gates in the cgexpr INLINE set (B6),
|
||||
* never reaching the :2456 funnel. Both stages runtime-correct;
|
||||
* byte-id rides B6. */
|
||||
{ "wstore_a_bound_b6",
|
||||
/* C1-CORR-2 → GRADUATED at B6-c1: the ident-lhs N_ASSIGN tagged
|
||||
* store gate (:6359) was the cgexpr INLINE peel B5 could not
|
||||
* reach; the B6-c1 chase closed it (pins-follow-the-layer, ken
|
||||
* B6 oracle C1 seed). */
|
||||
{ "wstore_a_2lvl",
|
||||
"package main;\n"
|
||||
"type u0 = (void | i64);\n"
|
||||
"type u = u0;\n"
|
||||
@@ -286,7 +284,7 @@ static const struct row rows[] = {
|
||||
" case void => { return 2; };\n"
|
||||
" };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, 0, K_RUN_NOID, NULL }, /* byte-id: B6 */
|
||||
"};\n", 0, 0, K_RUN, NULL }, /* graduated: B6-c1 */
|
||||
/* C1-CORR-1 → GRADUATED at c3: the residual divergence was
|
||||
* exactly three paired return-position tag syntheses — the
|
||||
* cgreturn return-route family; the c3 rt chase closed it
|
||||
|
||||
273
test/wcc/944_alias_cgen_b6_run.c
Normal file
273
test/wcc/944_alias_cgen_b6_run.c
Normal file
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* 944_alias_cgen_b6_run — #5 alias arc F2b (B6 train): the cgen.c
|
||||
* cgexpr/cgstmt INLINE single-peel sweep through type_chase_named, by
|
||||
* consumer family — c1 assign/reassign (9 lines), c2 call-arg (8),
|
||||
* c3 addr-of/field-walk/index spine (14), c4 cast/is/try (10),
|
||||
* c5 reads/len/globals (8). All cs-only: every graduation is a
|
||||
* DIVERGE→byte-id flip (cs aligns UP to ww's already-chasing asm);
|
||||
* zero selfhost/lib bytes move across the train, so the _ww binaries
|
||||
* stay bit-identical (the crossing detector).
|
||||
*
|
||||
* Row sources are ken's B6 first-position oracle probes
|
||||
* (/tmp/ken_b5/src/kb6_*, .ai/ken-b6-oracle.md, matrix at 4cac1cb).
|
||||
*
|
||||
* row | shape (oracle row) | cs/ww
|
||||
* --------------------+-------------------------------------+------
|
||||
* ---- c1 (assign/reassign: :6359 :6403/:6405 :6460/:6462 -------
|
||||
* :6518 + cgstmt :11696 :12047 :13625) -------------------
|
||||
* streassign_2lvl | kb6_streassign: 2-lvl alias str |
|
||||
* | reassign `b = a` — cs copied WORD0 |
|
||||
* | (ptr) ONLY, len/cap stale (silent |
|
||||
* | exit 1); the :6518 lu gate fell to |
|
||||
* | the scalar default. LIVE graduation | 0/0
|
||||
* wstore_a (B5 file) | kb5_wstore_a graduates K_RUN_NOID → |
|
||||
* | K_RUN in 944_alias_cgen_b5_run.c — |
|
||||
* | the ident-lhs N_ASSIGN tagged gate |
|
||||
* | (:6359) was the divergence (ken |
|
||||
* | C1-CORR-2, he owns the flip) | 0/0
|
||||
* sreassign_2lvl | kb6_sreassign: whole-struct alias |
|
||||
* | reassign — latent control | 0/0
|
||||
* dassign_2lvl | kb6_dassign: (*p).f= over alias ptr |
|
||||
* | — latent control | 0/0
|
||||
*
|
||||
* K_RUN rows build+run BOTH drivers (cs exit==cswant, ww exit==wwwant)
|
||||
* and assert cstage/wwstage asm byte-id. K_BUILDERR rows must FAIL
|
||||
* with experr on BOTH drivers; experr_ww overrides the ww-side text
|
||||
* when the two stages loud at DIFFERENT sites (per-stage texts).
|
||||
* NNN<950, self-contained /tmp sources, no imports (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, exits==wants, + byte-id */
|
||||
#define K_BUILDERR 1 /* build FAILS with experr on BOTH drivers;
|
||||
* experr_ww overrides the ww-side text */
|
||||
|
||||
struct row { const char *label; const char *src;
|
||||
int cswant; int wwwant; int kind;
|
||||
const char *experr; const char *experr_ww; };
|
||||
|
||||
/* errlog_has — a builderr cell 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[] = {
|
||||
/* ---- c1: assign/reassign family */
|
||||
/* LIVE c1 graduation: the :6518 reassign gate single-peeled the
|
||||
* 2-level alias str lhs, missed the TY_STR kind test, and fell
|
||||
* to the scalar default — ONE MOVQ stored the ptr word, len/cap
|
||||
* kept the dead value's header (cs silent exit 1, ww correct:
|
||||
* full 3-word {ptr,len,cap} store, Hare value semantics). */
|
||||
{ "streassign_2lvl",
|
||||
"package main;\n"
|
||||
"type ms0 = str;\n"
|
||||
"type ms = ms0;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let a: ms = \"hello\";\n"
|
||||
" let b: ms = \"x\";\n"
|
||||
" b = a;\n"
|
||||
" if (len(b) != 5) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, 0, K_RUN, NULL, NULL },
|
||||
{ "sreassign_2lvl",
|
||||
"package main;\n"
|
||||
"type st0 = struct { a: i64, b: i64, c: i64 };\n"
|
||||
"type st = st0;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let x: st; x.a = 1; x.b = 2; x.c = 3;\n"
|
||||
" let y: st; y.a = 0; y.b = 0; y.c = 0;\n"
|
||||
" y = x;\n"
|
||||
" if (y.c != 3 || y.b != 2) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, 0, K_RUN, NULL, NULL },
|
||||
{ "dassign_2lvl",
|
||||
"package main;\n"
|
||||
"type st0 = struct { a: i64, b: i64 };\n"
|
||||
"type st = st0;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let x: st; x.a = 1; x.b = 2;\n"
|
||||
" let p: *st = &x;\n"
|
||||
" (*p).b = 9;\n"
|
||||
" if (x.b != 9) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, 0, K_RUN, NULL, NULL },
|
||||
};
|
||||
|
||||
static int
|
||||
run_driver(const char *driver, const struct row *r, int i, int expect_err,
|
||||
int want, const char *experr)
|
||||
{
|
||||
char src[96], tmpdir[96], errf[96], cmd[1024];
|
||||
snprintf(src, sizeof src, "/tmp/ab6_%d_%d.ww", getpid(), i);
|
||||
snprintf(tmpdir, sizeof tmpdir, "/tmp/ab6_%d_d_%d", getpid(), i);
|
||||
snprintf(errf, sizeof errf, "/tmp/ab6_%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 (expect_err) {
|
||||
int ok = (brc != 0)
|
||||
&& (experr == NULL || errlog_has(errf, experr));
|
||||
if (!ok)
|
||||
fprintf(stderr, "row[%s]: %s expected loud builderr "
|
||||
"\"%s\" (brc=%d)\n", r->label, driver,
|
||||
experr ? 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 != want) {
|
||||
fprintf(stderr, "row[%s]: %s exit %d, want %d\n",
|
||||
r->label, driver, got, 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/ab6_asm_%d_%d.ww", getpid(), i);
|
||||
snprintf(cs, sizeof cs, "/tmp/ab6_asm_%d_%d_c.s", getpid(), i);
|
||||
snprintf(ws, sizeof ws, "/tmp/ab6_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++;
|
||||
int cs_err = rows[i].kind == K_BUILDERR;
|
||||
if (run_driver(cdrv, &rows[i], i, cs_err,
|
||||
rows[i].cswant, rows[i].experr) != 0) fail++;
|
||||
}
|
||||
if (access(wdrv, X_OK) == 0) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
total++;
|
||||
int ww_err = rows[i].kind == K_BUILDERR;
|
||||
const char *we = rows[i].experr_ww
|
||||
? rows[i].experr_ww : rows[i].experr;
|
||||
if (run_driver(wdrv, &rows[i], i, ww_err,
|
||||
rows[i].wwwant, we) != 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_cgen_b6: %d/%d checks failed\n",
|
||||
fail, total);
|
||||
return 1;
|
||||
}
|
||||
printf("alias_cgen_b6: %d/%d ok\n", total, total);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user