cgen: B6-c2 call-arg family single peels fold into type_chase_named — 8 lines, loud-preserving
The exact B6-c2 set (rob b6 spec §2): :8402 (callee fn-type resolve cu),
:8435 (variadic slice param vsu), :8561/:8563 + :8577/:8579 (tagged
widen-detect pu/au pairs, arg-class + #38b MEMORY-class) + the two
LOUD-PRESERVING chases :8829 (float-struct rule-7 fatal st) and :8934
(#32 tuple-arg rule-7 fatal targ). Raw `->under` in cgen.c 49→41.
LOUD-PRESERVING discipline: the :8829/:8934 chases widen what the gate
SEES, never what it ACCEPTS. DESIGNED ACCEPTANCE NARROWING (ken b6
oracle c2): kb6_fsarg2 — a 1-level-alias float-struct from a non-ident
source previously DODGED the #271/#165 fatal via the single peel; cs
accepted and GP-passed it runtime-correct by self-consistent luck
(caller+callee agreed on the wrong transport, no SSE eightbyte). Post-
c2 cs louds with the pinned #271/#165 text. ww's cell was already loud
at its own alias-return bound (#272/#276/#277 class) — fsarg2_bound
pins BOTH texts per-stage (experr_ww). fsarg0 plain control stays loud
both stages. :8934 is WATCH-ONLY (alias tuple-args are checker-blocked
upstream, #86/#99): kb5_tuparg_c two-key cells verified unmoved
(cs ok/0 + ww ok/1).
TRAIN INVARIANT: cs-only; w6c_ww/ww_ww bit-identical to the 4cac1cb
baselines (b6bddc8e…/4e9ca874…). cs movers bounded to exactly
kb6_fsarg2 (run-cell ok/0→ERR, no asm emitted — zero run-row movers);
rest of the corpus + five mains byte-NEUTRAL; kw1_101/fill2/tuparg_c/
xampdef/amplen1 detectors unmoved; 989 ratchet zero flips. kb6_sarg /
kb6_strarg / kb6_fsarg (ident twin) latent byte-NEUTRAL per ken's
structural bound.
944_alias_cgen_b6_run grows 3→8 rows, 9→22 checks: fsarg0_loud_ctl +
fsarg2_bound (per-stage experr pins; row struct gains experr_ww for
two-site loud pairs) + fsarg_ident_ctl/sarg_2lvl/strarg_2lvl controls.
All 944-family suites green; sizelint 0.
This commit is contained in:
@@ -8398,8 +8398,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
* its declared parameter type — needed to detect implicit
|
||||
* widening of a concrete variant into a tagged-union slot. */
|
||||
Type *callee_t = n->lhs ? n->lhs->type : NULL;
|
||||
Type *cu = (callee_t && callee_t->kind == TY_NAMED) ?
|
||||
callee_t->under : callee_t;
|
||||
Type *cu = type_chase_named(callee_t);
|
||||
Tparam *callee_params = (cu && cu->kind == TY_FN) ?
|
||||
cu->params : NULL;
|
||||
/* Hare-style variadic last param: gather N tail args into a
|
||||
@@ -8431,8 +8430,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
argcount = nfixed + 1;
|
||||
} else {
|
||||
Type *vst = var_p->type;
|
||||
Type *vsu = (vst && vst->kind == TY_NAMED)
|
||||
? vst->under : vst;
|
||||
Type *vsu = type_chase_named(vst);
|
||||
Type *velem = (vsu && vsu->kind == TY_SLICE)
|
||||
? vsu->sub : NULL;
|
||||
int esz = (velem && velem->size)
|
||||
@@ -8557,10 +8555,8 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
Type *at = args[i] ? args[i]->type : NULL;
|
||||
int psz = tagged_arg_size(p->type);
|
||||
if (psz > 0) {
|
||||
Type *pu = (p->type && p->type->kind == TY_NAMED)
|
||||
? p->type->under : p->type;
|
||||
Type *au = (at && at->kind == TY_NAMED)
|
||||
? at->under : at;
|
||||
Type *pu = type_chase_named(p->type);
|
||||
Type *au = type_chase_named(at);
|
||||
int same = (pu == au) || type_eq(p->type, at);
|
||||
if (!same) {
|
||||
widen[i] = 1;
|
||||
@@ -8573,10 +8569,8 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
int msz = tagged_memarg_size(p->type);
|
||||
if (msz > 0) {
|
||||
memarg[i] = msz;
|
||||
Type *pu = (p->type && p->type->kind == TY_NAMED)
|
||||
? p->type->under : p->type;
|
||||
Type *au = (at && at->kind == TY_NAMED)
|
||||
? at->under : at;
|
||||
Type *pu = type_chase_named(p->type);
|
||||
Type *au = type_chase_named(at);
|
||||
int same = (pu == au) || type_eq(p->type, at);
|
||||
if (!same) {
|
||||
widen[i] = 1;
|
||||
@@ -8824,9 +8818,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
* ≤16B struct with any float field; the wwstage
|
||||
* tinfo mirror uses the same predicate). */
|
||||
{
|
||||
Type *st = args[i]->type;
|
||||
if (st && st->kind == TY_NAMED)
|
||||
st = st->under;
|
||||
Type *st = type_chase_named(args[i]->type);
|
||||
if (st && st->kind == TY_STRUCT
|
||||
&& st->size <= 16) {
|
||||
int f32;
|
||||
@@ -8929,9 +8921,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
* pre-fix it fell to the scalar single-PUSHQ default
|
||||
* and silently skewed every later arg register. */
|
||||
if (tuparg_push == NULL) {
|
||||
Type *targ = args[i]->type;
|
||||
if (targ && targ->kind == TY_NAMED)
|
||||
targ = targ->under;
|
||||
Type *targ = type_chase_named(args[i]->type);
|
||||
if (targ && targ->kind == TY_TUPLE)
|
||||
fatal("#32: tuple arg from unsupported "
|
||||
"source shape %d (call/ident/"
|
||||
|
||||
@@ -29,6 +29,32 @@
|
||||
* | reassign — latent control | 0/0
|
||||
* dassign_2lvl | kb6_dassign: (*p).f= over alias ptr |
|
||||
* | — latent control | 0/0
|
||||
* ---- c2 (call-arg: :8402 :8435 :8561/:8563/:8577/:8579 --------
|
||||
* + LOUD-PRESERVING :8829 :8934) ------------------------
|
||||
* fsarg0_loud_ctl | kb6_fsarg0: PLAIN float-struct from |
|
||||
* | a non-ident source — #271/#165 loud |
|
||||
* | BOTH stages (control, twin texts) | err/err
|
||||
* fsarg2_bound | kb6_fsarg2: 1-alias-level respell — |
|
||||
* | pre-c2 the :8829 single-peel let |
|
||||
* | the alias DODGE the fatal; cs GP- |
|
||||
* | passed by self-consistent luck. |
|
||||
* | DESIGNED NARROWING: cs now louds |
|
||||
* | with the pinned #271/#165 text |
|
||||
* | ("widen what the gate SEES, never |
|
||||
* | what it ACCEPTS"). ww's loud is its |
|
||||
* | own alias-return bound (#272/#277 |
|
||||
* | class, experr_ww) — per-stage texts | err/err
|
||||
* fsarg_ident_ctl | kb6_fsarg: IDENT-source alias twin |
|
||||
* | — ident domain out of the :8829 |
|
||||
* | gate, latent control | 0/0
|
||||
* sarg_2lvl | kb6_sarg: >16B alias struct arg — |
|
||||
* | latent (B5 helper chases carry the |
|
||||
* | type layer) | 0/0
|
||||
* strarg_2lvl | kb6_strarg: alias str arg — latent | 0/0
|
||||
* (:8934 tuple loud is WATCH-ONLY: alias spellings are |
|
||||
* checker-blocked upstream (#86/#99) — the pin is the b5 |
|
||||
* suite's tuparg_cast_bound99 two-key cells, which must |
|
||||
* not move.) |
|
||||
*
|
||||
* 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
|
||||
@@ -131,6 +157,78 @@ static const struct row rows[] = {
|
||||
" if (x.b != 9) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, 0, K_RUN, NULL, NULL },
|
||||
/* ---- c2: call-arg family */
|
||||
{ "fsarg0_loud_ctl",
|
||||
"package main;\n"
|
||||
"type fs0 = struct { x: f64 };\n"
|
||||
"fn mk() fs0 = {\n"
|
||||
" let s: fs0; s.x = 2.5;\n"
|
||||
" return s;\n"
|
||||
"};\n"
|
||||
"fn g(p: fs0) f64 = { return p.x; };\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" if (g(mk()) != 2.5) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, 0, K_BUILDERR,
|
||||
"#271/#165: float-bearing struct arg from a non-ident source",
|
||||
NULL },
|
||||
/* DESIGNED ACCEPTANCE NARROWING (B6-c2): pre-c2 cs accepted and
|
||||
* GP-passed this float struct correct-by-self-consistent-luck
|
||||
* (caller+callee agreed on the wrong transport) — the :8829
|
||||
* single peel let a 1-level alias dodge the rule-7 fatal. The
|
||||
* chase widens what the gate SEES; the loud stays loud for the
|
||||
* shapes it guards. ww's cell was ALREADY loud at its own
|
||||
* alias-return bound (#272/#276/#277 class) — different site,
|
||||
* per-stage experr. */
|
||||
{ "fsarg2_bound",
|
||||
"package main;\n"
|
||||
"type fs0 = struct { x: f64 };\n"
|
||||
"type fs = fs0;\n"
|
||||
"fn mk() fs = {\n"
|
||||
" let s: fs; s.x = 2.5;\n"
|
||||
" return s;\n"
|
||||
"};\n"
|
||||
"fn g(p: fs) f64 = { return p.x; };\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" if (g(mk()) != 2.5) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, 0, K_BUILDERR,
|
||||
"#271/#165: float-bearing struct arg from a non-ident source",
|
||||
"#272/#276/#277: aggregate return reaches scalar default" },
|
||||
{ "fsarg_ident_ctl",
|
||||
"package main;\n"
|
||||
"type fs0 = struct { x: f64 };\n"
|
||||
"type fs = fs0;\n"
|
||||
"fn mk() fs0 = {\n"
|
||||
" let s: fs0; s.x = 2.5;\n"
|
||||
" return s;\n"
|
||||
"};\n"
|
||||
"fn g(p: fs) f64 = { return p.x; };\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let v: fs = mk();\n"
|
||||
" if (g(v) != 2.5) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, 0, K_RUN, NULL, NULL },
|
||||
{ "sarg_2lvl",
|
||||
"package main;\n"
|
||||
"type big0 = struct { a: i64, b: i64, c: i64 };\n"
|
||||
"type big = big0;\n"
|
||||
"fn g(p: big) i64 = { return p.a + p.c; };\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let s: big; s.a = 4; s.b = 5; s.c = 9;\n"
|
||||
" if (g(s) != 13) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, 0, K_RUN, NULL, NULL },
|
||||
{ "strarg_2lvl",
|
||||
"package main;\n"
|
||||
"type ms0 = str;\n"
|
||||
"type ms = ms0;\n"
|
||||
"fn g(s: ms) i64 = { return len(s): i64; };\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let a: ms = \"hello\";\n"
|
||||
" if (g(a) != 5) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0, 0, K_RUN, NULL, NULL },
|
||||
};
|
||||
|
||||
static int
|
||||
|
||||
Reference in New Issue
Block a user