cgen: #49 aggregate-ASSIGN word0-only family — one mem-to-mem funnel (cg_aggcopy), both stages
Whole-aggregate reassignment `b = a` fell to the N_ASSIGN scalar tail
and copied ONE MOVQ — word 0 of any struct/array/tuple — in BOTH
stages, byte-identical, gate-blind (ken f49_min asm proof; latent
because lib style is let-init, whose #265/#268 copy is full-width).
Same class at three more positions: struct-lit FIELD init from an
ident source (`outer{.., r = r}`, the #38 non-tagged half), the deref
place `*p = s` (#31-A), and the module-let global `g = a` / `g = pt{..}`.
Fix: extract the C1.25 assign-resolver word-copy tail verbatim into
cg_aggcopy/aggcopy — the ONE place-resolved (SI)->(BX) aggregate copy
— and wire it at the N_ASSIGN ident-aggregate arm (local + global),
the deref-place divert into the existing resolver aggregate arm, and
the structlit-fill aggregate-field arm, all fed by aggarg_srcaddr
(the closed #265/#268 dispatch). The new arms key on the FULL alias
chase (type_chase_named / chased stamped tinfo, the #22 precedent) in
BOTH stages — the region's single-peel `lu`/`fu` would miss
`type b = a; type a = struct` on cstage while the wwstage twin fired
(ken R1, gA3b: master cs ran the word0 corruption, exit 2; now 0).
Non-addressable aggregate rhs (tuple-lit, unhandled call shapes) dies
LOUD (rule 7) instead of silently truncating: #31-E `*p = (3,4)` and
#31-G's deref flavor `*p = mk()` are now loud both stages (the INDEX
flavor `a[i] = mk()` stays in the legacy INDEX arm — receive
machinery, not this funnel; still filed under #31). #31-B rides: the
cstage-only <=24B gate before cg_structlit_fill_bp is lifted (the
wwstage twin never gated — a >24B literal reassign was
cs-zero/ww-filled, rule-10 break). Global structlit reassign rides
the existing DST_GLOBAL fill machinery.
Unsplit (rule 11): the assign arm, fill arm and deref divert all
route through the one new funnel (cg_aggcopy + aggarg_srcaddr) in
both stages; splitting by site or by stage would ship a transient
cs!=ww (gate-red) or a funnel with no consumer.
941 t2_reject_chain_arg: the row's tuple-LITERAL field fill now louds
at the #49 fill arm before reaching the pinned ARG-site reject; the
fill switches to an ident source (newly working via the fill arm) so
the original arg-site pin still fires.
test/wcc/812_agg_assign_width.c: 17 runtime-readback rows (the only
oracle for a gate-blind class) + per-row asm byte-id; every row fails
at 7545bf7 (ken matrix f49_min/f49b/f49c/fA_16b/f38b + gA3b/gA6 +
impl-A probes; reviewer-A re-probed 5 rows + the gA2 12B shape at a
master git-archive scratch). Alias rows use FIELD-WISE init: the
struct-LIT spelling louds earlier at the pre-existing task-#7
aggregate-let bound on wwstage (the #5 alias-arc's hole, not this
funnel's). Reviewer-A amendment (test-only, K5 self-certify): add
the ken-gA2 odd-size row (12B {u32,u32,u32}, maxalign 4 — pins the
MOVL tail; master both stages exit 3) and gA4's neighbor guards on
the deref row, completing ken's validated matrix in the committed
suite.
This commit is contained in:
15
Makefile
15
Makefile
@@ -399,6 +399,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
|
||||
$(BIN)/test_arrlit_overlong \
|
||||
$(BIN)/test_idx_structlit_store \
|
||||
$(BIN)/test_inferred_let_struct \
|
||||
$(BIN)/test_agg_assign_width \
|
||||
$(BIN)/test_placeaddr_store \
|
||||
$(BIN)/test_tryprop_multisuccess \
|
||||
$(BIN)/test_append_place \
|
||||
@@ -1101,6 +1102,20 @@ $(BIN)/test_inferred_let_struct: test/wcc/811_inferred_let_struct.c \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
# Task #49 (Family A, ken silent-set triage): whole-aggregate ASSIGN
|
||||
# `b = a` copied word0 only — one MOVQ for any struct/array/tuple — in
|
||||
# BOTH stages, byte-identical, gate-blind. Same class at the structlit
|
||||
# fill field-from-ident, the deref place (#31-A) and the module-let
|
||||
# global. Fixed via the ONE mem-to-mem funnel (cg_aggcopy/aggcopy fed
|
||||
# by aggarg_srcaddr); non-addressable aggregate rhs dies loud. Runtime
|
||||
# readback rows (the only oracle for a gate-blind class) + per-row
|
||||
# asm byte-id.
|
||||
$(BIN)/test_agg_assign_width: test/wcc/812_agg_assign_width.c \
|
||||
$(BIN)/ww $(BIN)/w6c $(BIN)/w6c_ww $(BIN)/w6a $(BIN)/w6l \
|
||||
$(BIN)/ww_ww \
|
||||
$(LIB)/libwwrt.a | $(BIN)
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
# F8+F9 (tasks #5/#12, regex fold-2b): `?` interim single-success gate
|
||||
# (|success| > 1 loud-rejected on BOTH stages until task #14's
|
||||
# subset-union typing) + direct `f()? is T` / `match (f()?)` reject
|
||||
|
||||
Reference in New Issue
Block a user