From ca8c78e97d196a8512ad5273bc631d201cce00c3 Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Tue, 2 Jun 2026 04:47:56 +0900 Subject: [PATCH] test/949: slice-of-non-array-field call-arg guard rows (#257) The #257 call-arg fix routes the N_SLICE base through the array-gated cg_dotbase_addr/dotbaseaddr helper. Add the load-bearing deviation guard: a slice of a []T field and of a str field passed straight as a call arg must FALL THROUGH the gate to cgexpr (header .ptr load), not take the field address. Both also exercise the N_DOT esz extension on the fall-through arm (re-slice by element width). cs==ww byte-id. --- test/wcc/949_dotbase_addr_slice_run.c | 29 +++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) 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 } };