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.
66 lines
2.2 KiB
Plaintext
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);
|
|
};
|