cgen: B5-c2 #73 graduation — the 6 tripwired field gates chase, tripwire deleted
Close-by-construction replacing containment — the designed graduation
path from F1-c1's commit body. The 6 fld_alias_tripwire call sites
(indexed-elem field store/read, heap struct-lit field fill, tuple-elem
read, ptr-chain field read, static struct-lit emit) chase their fu
through type_chase_named; the 6 tripwire calls AND the helper itself
(incl. its :447 peel) are DELETED. Raw `->under` in cgen.c 69→62.
#73 CLOSES.
TRAIN INVARIANT holds: cs-only; w6c_ww/ww_ww bit-identical to the
bcd948d baseline md5s (28ad889042bad8006f1997cbcec94805 /
4e9ca8741f19e1f68219ff799a5e5a14). ZERO new corpus movers vs the c1
tip (kb*/kna corpus + five mains byte-NEUTRAL — the chased gates only
fire on 2+-level alias aggregate fields, none in corpus).
Gate-arm graduations (pre = loud "#73" fatal on cs, ww ok/0; post =
0/0 BYTE-ID): slice/str/tagged arms at the indexed STORE gate
(g73_idxstore/g73_strfield/g73_tagfield), slice arm at the indexed
READ / ptr-chain READ / tuple-elem READ gates (g73_idxread/g73_ptrread/
g73_tupread), nested-struct arm at the static emit gate
(g73_static_struct). The existing 944_alias_accept_run tripwire bound
row graduates K_BUILDERR_CS → K_RUN.
Two arms cannot pin the full 0/0 byte-id cell — documented, not silent:
- heap fill (g73_heapfill, COMPILE-only pin): bare /tmp programs
never link malloc (both stages, pre-existing infra) and ww's
deref-field READ carries the #24-kin field(SB) leak; the chased
FILL bytes verified byte-id by hand against the plain (non-alias)
control — divergence shape identical, all of it in the pre-existing
read sites.
- str-field static emit (g73_static_str): the #73 fatal gave way to
the pre-existing #129 A.2 foldability loud on cs — now both-loud
twin texts (fill0 class), pinned as K_BUILDERR.
- struct-copy arm: NO runnable repro reaches these gates — indexed
whole-struct field reads take the (already chased, byte-id) address
spine, and tuple-of-struct louds upstream on BOTH stages (#54-kin
"aggregate init from unhandled rhs shape"). The arm's only carrier
was the heap gate, covered by the compile pin above.
944_alias_cgen_b5_run grows 16→25 rows (65 checks); all 944-family
suites green; sizelint 0.
This commit is contained in:
@@ -433,32 +433,6 @@ fldstoreop(Type *t, int sz)
|
||||
return A_MOVQ;
|
||||
}
|
||||
|
||||
/* fld_alias_tripwire — #73 guard at the single-peel field gates this
|
||||
* fold did NOT chase. The #5-F1 acceptance admits 2+-level alias field
|
||||
* types everywhere; a still-NAMED type after one peel skips a gate's
|
||||
* multi-word arms (slice/str 3-word, tagged widener, struct copy) for
|
||||
* a word0 scalar tail — accept-and-corrupt. Loud over silent (rule 7);
|
||||
* chase + per-arm probes are task #73. Fires ONLY on 2+-level chains
|
||||
* over an aggregate base: <=1-level (the entire pre-#5-F1-legal set)
|
||||
* and scalar/float bases (width-driven tails, depth-safe) never fire. */
|
||||
static void
|
||||
fld_alias_tripwire(Type *ft, const char *site)
|
||||
{
|
||||
Type *u = (ft && ft->kind == TY_NAMED) ? ft->under : ft;
|
||||
if (u == NULL || u->kind != TY_NAMED) return;
|
||||
Type *base = type_chase_named(u);
|
||||
if (base == NULL) return;
|
||||
switch (base->kind) {
|
||||
case TY_SLICE: case TY_STR: case TY_TAGGED:
|
||||
case TY_STRUCT: case TY_TUPLE: case TY_ARRAY:
|
||||
fatal("%s: 2+-level alias field type '%s' at unswept "
|
||||
"single-peel gate (#73)", site,
|
||||
ft->name ? ft->name : "?");
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* castsrcprim — structural (size, unsigned) of an N_CAST's source
|
||||
* expression, mirroring wwstage's exprprimresolved in
|
||||
* selfhost/cmd/wcc/cgenutil.ww. The cgen-stage match has to be
|
||||
@@ -5079,10 +5053,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
if (f != NULL && (is_arr || is_sl || is_ptr)
|
||||
&& off != 0) {
|
||||
Type *ft = f->type;
|
||||
fld_alias_tripwire(ft,
|
||||
"indexed-elem field store");
|
||||
Type *fu = (ft && ft->kind == TY_NAMED)
|
||||
? ft->under : ft;
|
||||
Type *fu = type_chase_named(ft);
|
||||
int fsz = (int)(ft ? ft->size : 8);
|
||||
int store_op = fldstoreop(ft, fsz);
|
||||
int foff = (int)f->offset;
|
||||
@@ -7870,10 +7841,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
* CX=cap). Route the heap base through DX so all
|
||||
* three survive — CX now holds cap, BX holds len
|
||||
* (#1/Phase 3). */
|
||||
fld_alias_tripwire(ftype,
|
||||
"heap struct-lit field fill");
|
||||
Type *fu = (ftype && ftype->kind == TY_NAMED)
|
||||
? ftype->under : ftype;
|
||||
Type *fu = type_chase_named(ftype);
|
||||
if (fu && fu->kind == TY_STR) {
|
||||
ins2(c, A_MOVQ, amem(D_SP, 0), areg(D_DX));
|
||||
ins2(c, A_MOVQ, areg(D_AX),
|
||||
@@ -10657,10 +10625,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
}
|
||||
if (tp != NULL) {
|
||||
int fsz = (int)(tp->type ? tp->type->size : 8);
|
||||
fld_alias_tripwire(tp->type,
|
||||
"tuple-elem read");
|
||||
Type *fu = (tp->type && tp->type->kind == TY_NAMED)
|
||||
? tp->type->under : tp->type;
|
||||
Type *fu = type_chase_named(tp->type);
|
||||
int op = fldloadop(tp->type, fsz);
|
||||
int off = localfind(locals, n->lhs->str);
|
||||
/* C-t3 (#48): GLOBAL tuple base — LEAQ the
|
||||
@@ -10990,10 +10955,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
if (strcmp(f->name, n->str) != 0) continue;
|
||||
cgexpr(c, n->lhs, locals); /* AX = inner ptr */
|
||||
Type *ft = f->type;
|
||||
fld_alias_tripwire(ft,
|
||||
"ptr-chain field read");
|
||||
Type *fu = (ft && ft->kind == TY_NAMED)
|
||||
? ft->under : ft;
|
||||
Type *fu = type_chase_named(ft);
|
||||
/* tagged leaf (#38a): AX holds the *struct
|
||||
* base and the tagged cursor targets AX
|
||||
* (tag) — stage the base in BX, then the
|
||||
@@ -11149,10 +11111,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
areg(D_AX));
|
||||
int foff = (int)f->offset;
|
||||
Type *ft = f->type;
|
||||
fld_alias_tripwire(ft,
|
||||
"indexed-elem field read");
|
||||
Type *fu = (ft && ft->kind == TY_NAMED)
|
||||
? ft->under : ft;
|
||||
Type *fu = type_chase_named(ft);
|
||||
/* #270-1a: an `[N]T`-typed field of an
|
||||
* array element (`a[i].m[j]`) — leave the
|
||||
* field's ADDRESS, a base for the outer
|
||||
@@ -14283,9 +14242,7 @@ emit_struct_lit_bytes(FILE *out, Cg *c, Type *t, Node *rhs, u64 base)
|
||||
}
|
||||
Node *vr = v;
|
||||
while (vr != NULL && vr->kind == N_CAST) vr = vr->lhs;
|
||||
fld_alias_tripwire(f->type, "static struct-lit emit");
|
||||
Type *fu = (f->type && f->type->kind == TY_NAMED)
|
||||
? f->type->under : f->type;
|
||||
Type *fu = type_chase_named(f->type);
|
||||
if (fu && fu->kind == TY_STRUCT) {
|
||||
/* Recurse into nested struct lit. Pre-#145 the parser/
|
||||
* checker has its own gap on inner-N_STRUCTLIT field
|
||||
|
||||
Reference in New Issue
Block a user