// forrange_fieldbase_test — #70: by-value for-range over a NON-IDENT slice/str // base (field chain, indexed element, call result). Migrated from // test/wcc/937_forrange_fieldbase_run.c (value rows; cs==ww byte-id rides T2). // The two LOUD-reject rows (deref base #11, non-ident array base #70) stay as // runww //ww:error carriers under test/wcc/data/. // // Pre-#70 the range header stored the data POINTER into the bound temp and the // per-iteration code reused it as the base, so i was compared against the // pointer and the loop walked off the end (regex.finish SEGV); empty slices // coincidentally exited on ptr==0, so the byte-id gate held on both-wrong. Now // bound = len, base ptr spilled to its own slot. field_base_24B is the live // SEGV repro (24B str-header elements through a ptr field); eval_once pins the // range operand is captured once (a per-iteration field re-read would mis-sum). package forrange_fieldbase_test; type holder = struct { xs: []i64, name: str }; type holder2 = struct { xs: []i64, n: i64 }; type bag = struct { names: []str, n: i64 }; fn mk() []i64 = { let xs: []i64; append(xs, 7); append(xs, 8); return xs; }; @test fn field_base() void = { let h: holder = holder { xs = mk(), name = "h" }; let s1: i64 = 0; for (let v .. h.xs) { s1 += v; }; assert(s1 == 15); let p: *holder = &h; let s2: i64 = 0; for (let v .. p.xs) { s2 += v; }; assert(s2 == 15); }; @test fn field_base_24B() void = { let names: []str; append(names, "ab"); append(names, "cde"); let b: bag = bag { names = names, n = 2 }; let p: *bag = &b; let total: i64 = 0; for (let nm .. p.names) { total += (len(nm): i64); }; assert(total == 5); }; @test fn indexed_base() void = { let m: [][]i64; append(m, mk()); let s: i64 = 0; for (let v .. m[0]) { s += v; }; assert(s == 15); }; @test fn call_base() void = { let s: i64 = 0; for (let v .. mk()) { s += v; }; assert(s == 15); }; @test fn empty_field() void = { let h: holder = holder { name = "e", ... }; let hit: bool = false; for (let v .. h.xs) { hit = true; }; assert(!hit); }; @test fn eval_once() void = { let a: []i64; append(a, 7); append(a, 8); let b: []i64; append(b, 100); let h: holder2 = holder2 { xs = a, n = 0 }; let s: i64 = 0; for (let v .. h.xs) { s += v; h.xs = b; }; assert(s == 15); assert(len(h.xs) == 1); };