x.slicefield[:] / x.strfield[2:] emitted MOVQ $0 for the omitted hi
bound on BOTH stages (N_IDENT-gated dispatch; symmetric, so byte
identity never caught it) in all four sites: cgexpr N_SLICE + pushargs
(cstage), cgslice + pushargsrev (wwstage). The new arm re-evaluates
the pure field read for its {ptr,len,cap} header and takes .len,
covering local, viaptr, dot-chain, (*p), arr[i], and global inners.
Call inners still loud-reject upstream. Sibling of the #252/#257
array-field arms.
47 lines
1.1 KiB
Plaintext
47 lines
1.1 KiB
Plaintext
//ww:run
|
|
// Default-hi slice of a slice/str FIELD in call-ARG position — the
|
|
// pushargs twin of dotfield_slice_defhi. Pre-fix the pushargs
|
|
// N_SLICE default-hi arm was N_IDENT-gated on BOTH stages, so
|
|
// callees received a 0-length slice.
|
|
package main;
|
|
|
|
type inner = struct {
|
|
buf: []i32,
|
|
name: str,
|
|
};
|
|
|
|
type outer = struct {
|
|
pad: i64,
|
|
in: inner,
|
|
};
|
|
|
|
fn sum(xs: []i32) i32 = {
|
|
let t: i32 = 0;
|
|
let i: i32 = 0;
|
|
for (i < len(xs)) {
|
|
t += xs[i];
|
|
i += 1;
|
|
};
|
|
return t;
|
|
};
|
|
|
|
fn slen(s: str) i32 = {
|
|
return len(s);
|
|
};
|
|
|
|
export fn main() int = {
|
|
let arr: [4]i32 = [10, 20, 30, 40];
|
|
let v: inner = inner{ buf = arr[:], name = "hello" };
|
|
if (sum(v.buf[:]) != 100) { return 1; };
|
|
if (sum(v.buf[2:]) != 70) { return 2; };
|
|
if (slen(v.name[1:]) != 4) { return 3; };
|
|
let p: *inner = &v;
|
|
if (sum(p.buf[:]) != 100) { return 4; };
|
|
if (slen(p.name[2:]) != 3) { return 5; };
|
|
let o: outer = outer{ pad = 7, in = inner{ buf = arr[:], name = "world" } };
|
|
if (sum(o.in.buf[:]) != 100) { return 6; };
|
|
if (sum(o.in.buf[1:]) != 90) { return 7; };
|
|
if (slen(o.in.name[4:]) != 1) { return 8; };
|
|
return 0;
|
|
};
|