diff --git a/test/wcc/949_dotbase_addr_slice_run.c b/test/wcc/949_dotbase_addr_slice_run.c index f63521aa..c3f02f9f 100644 --- a/test/wcc/949_dotbase_addr_slice_run.c +++ b/test/wcc/949_dotbase_addr_slice_run.c @@ -451,6 +451,35 @@ static const struct row rows[] = { " a[1] = 66u8;\n" " return rd(a[1:4]);\n" "};\n", 66, 1 }, + /* Helper-deviation guard rows (load-bearing): a slice of a NON-array + * field (`[]T` field, str field) passed as a call arg must FALL + * THROUGH the array-gated cg_dotbase_addr/dotbaseaddr to cgexpr, + * which loads the field's slice/str HEADER .ptr — NOT take the field + * ADDRESS (that would treat the header words as inline array data). + * The N_DOT esz extension also applies on the fall-through arm: the + * slice is re-sliced by the element width (esz=4 for []i32), so + * q.v[1:3][0] = backing[1]. If the gate over-fired (emitted &field), + * .ptr would point at the header itself -> wrong value / segfault. */ + { "callarg_slicefield", + "package main;\n" + "type w = struct { v: []i32 };\n" + "fn rd(s: []i32) i32 = { return s[0]; };\n" + "export fn main() i32 = {\n" + " let backing: [4]i32;\n" + " backing[1] = 88;\n" + " let q: w;\n" + " q.v = backing[0:4];\n" + " return rd(q.v[1:3]);\n" + "};\n", 88, 1 }, + { "callarg_strfield", + "package main;\n" + "type w = struct { v: str };\n" + "fn rd(s: str) i32 = { return len(s): i32; };\n" + "export fn main() i32 = {\n" + " let q: w;\n" + " q.v = \"hello\";\n" + " return rd(q.v[1:4]);\n" + "};\n", 3, 1 }, { NULL, NULL, 0, 0 } };