Files
ww/test/lang/tupfieldsize_test.ww
Hojun-Cho 83f5956df2 test: banner purge + WHY-only comment sweep (rule 8)
Every section banner dies (103 -> 0) across test/lang, the observer
suites, the C carriers, and the five comment-heavy corpus fixtures;
banner provenance (#N cites, carrier numbers, repair-cluster labels)
folded into headers or adjacent WHY comments. Narration deleted; row
provenance, ref cites, divergence pins, and layout contracts kept
(fwd-ref decl-order guards and bootstrap-gate corpus rationale
restored where the sweep over-cut). Comment-only proven: all 3742
wwbuild workdir .s byte-identical before/after; test-commit and
test-byteid (161 lang + 1399 data, 0 pinned-divergent) green.
2026-08-08 21:40:23 +09:00

66 lines
2.2 KiB
Plaintext

// F7-c4 (#43) + #40: a for-range destructure over an array
// of tuples must stride by the tuple's TRUE size, and a slice/str/nested-tuple
// FIELD carries its full 24B width, not the 8B scalar default; the destructure
// LOAD-into-binding must copy the full extent of a sz>8 aggregate binding (the
// recurring dropped word is the CAP). Migrated from test/wcc/989_tupfieldsize_run.c.
//
// THE BUG (cat-A silent miscompile, gate-blind): wwstage paramfieldsize
// (selfhost/cmd/wcc/cgenstmt.ww) had no N_TSLICE / N_TTUPLE arm, so a `[]T`
// tuple-field sized 8 instead of its 24B header; and the destructure copy
// landed only the PTR word, dropping .len/.cap. The fix adds the N_TSLICE arm
// (tyslicesize()=24, rule-13) + the N_TTUPLE arm, and copies the binding's full
// extent (cgen.c N_FORRANGE + cgenstmt.ww cgforrange twin), aligning wwstage UP.
//
// The cap row slices the bases so cap != len, teething the recurring dropped
// CAP word; a ptr+len-only set would pass green while cap stayed stale.
//
// The C driver ran each row on both stages + asserted cs==ww exit; here the
// cstage run is test-lang (T1) and the byte-id is test-lang-byteid (T2).
package tupfieldsize_test;
@test fn len_read() void = {
let b0: []u8 = ['a', 'b'];
let b1: []u8 = ['x', 'y', 'z'];
let xs: [2]([]u8, i64);
xs[0] = (b0, 10);
xs[1] = (b1, 30);
let sum: i64 = 0;
for (let (b, n) .. xs) {
sum = sum + len(b): i64 + n;
};
assert(sum: int == 45);
};
@test fn cap_read() void = {
let base0: []u8 = ['a', 'b', 'c', 'd'];
let base1: []u8 = ['p', 'q', 'r', 's', 't'];
let xs: [2]([]u8, i64);
xs[0] = (base0[0:2], 10);
xs[1] = (base1[0:3], 30);
let sum: i64 = 0;
for (let (b, n) .. xs) {
sum = sum + b.cap: i64 + n;
};
assert(sum: int == 49);
};
@test fn ptr_read() void = {
let b0: []u8 = ['a', 'b'];
let b1: []u8 = ['x', 'y', 'z'];
let xs: [2]([]u8, i64);
xs[0] = (b0, 10);
xs[1] = (b1, 30);
let sum: i64 = 0;
for (let (b, n) .. xs) { sum = sum + b[0]: i64; };
assert(sum: int == 217);
};
@test fn scalar_tuple_ctl() void = {
let xs: [2](i64, i64);
xs[0] = (3, 10); xs[1] = (5, 30);
let sum: i64 = 0;
for (let (a, b) .. xs) { sum = sum + a + b; };
assert(sum: int == 48);
};