Batch 2 of the test-arch reframe. These three are codegen-SHAPE tests,
not data-row tests: each subject is a distinct node shape (N_IDENT
module-global read; chained N_INDEX m[i][k]; index-base node-kind). A
[N]struct row-table would interpose its own N_INDEX/N_DOT lowering and
mask the shape under test, so each uses per-shape @test fns with direct
asserts (rob-ratified rule: table where the row is data, per-fn where
the row is a codegen shape). Lossless from the matching
989_{gunsigned,chainidx,idxarg}_run.c; additive (C kept); both stages green.
51 lines
2.0 KiB
Plaintext
51 lines
2.0 KiB
Plaintext
// idxarg_test — an INDEXED slice/str element passed as a call argument must
|
|
// push its full multi-word header, both stages, migrated from
|
|
// test/wcc/989_idxarg_run.c (#45/#46). pushargsrev sizes a call arg via
|
|
// nodeisslice/nodeisstr; pre-fix nodeisslice had no N_INDEX arm (#45, slice
|
|
// element fell to a 1-word scalar push) and nodeisstr's N_INDEX arm was a
|
|
// base-kind whitelist that only knew N_IDENT/N_DOT bases (#46, a non-ident/
|
|
// non-dot base fell through to a 1-word push). Either way the callee read
|
|
// garbage .len/.cap — a cat-A divergence invisible to byte-id.
|
|
//
|
|
// Each "row" is a distinct index-base SHAPE (slice element, N_CALL base,
|
|
// N_IDENT base, plain local control), not data, so this file uses per-shape
|
|
// asserts rather than the uniesc row-loop idiom.
|
|
|
|
package idxarg_test;
|
|
|
|
fn takeintlen(xs: []int) int = { return len(xs): int; };
|
|
fn takestrlen(s: str) int = { return len(s): int; };
|
|
|
|
fn getarr() []str = {
|
|
let a: []str = ["x", "ddddd", "zz"];
|
|
return a;
|
|
};
|
|
|
|
@test fn idx_slice_arg() void = {
|
|
// slice_elem_arg (#45): a []int slice element `rows[1]` as a call arg —
|
|
// pre-fix nodeisslice had no N_INDEX arm, so a 1-word push gave the
|
|
// callee garbage len. len(rows[1]) == len(b) == 2.
|
|
let a: []int = [10, 20, 30, 40];
|
|
let b: []int = [1, 2];
|
|
let rows: [2][]int = [a, b];
|
|
assert(takeintlen(rows[1]) == 2);
|
|
};
|
|
|
|
@test fn idx_str_arg() void = {
|
|
// call_str_elem (#46): an index whose base is an N_CALL (`getarr()[1]`)
|
|
// — the non-ident/non-dot base the old whitelist missed. len == 5.
|
|
assert(takestrlen(getarr()[1]) == 5);
|
|
|
|
// ident_str_elem (#46 control): an N_IDENT base `arr[1]` — the case the
|
|
// old whitelist DID handle; the stamp read must not regress it.
|
|
let arr: [3]str = ["x", "ddddd", "zz"];
|
|
assert(takestrlen(arr[1]) == 5);
|
|
};
|
|
|
|
@test fn idx_local_arg() void = {
|
|
// slice_local_arg (control): a plain non-indexed str/slice local arg
|
|
// (the c1 N_IDENT-local arm) — c2 must leave it alone. len == 3.
|
|
let xs: []int = [7, 8, 9];
|
|
assert(takeintlen(xs) == 3);
|
|
};
|