Files
ww/test/lang/aggregate_field_copy_test.ww
Hojun-Cho 078708770b cgen: route aggregate field-to-field assignment through the aggregate copier
The direct-field assignment arms enumerate CALL, STRUCTLIT, and local
IDENT producers; an addressable N_DOT/N_INDEX/deref rhs fell through to
the scalar tail, so a 16-byte struct field copied only its first word.
Resolve both places through the existing address funnels and use the
tail-aware aggregate copier. Both stages.
2026-08-07 22:59:52 +09:00

74 lines
1.6 KiB
Plaintext

// Addressable aggregate fields must copy every byte. A scalar fallback used
// to copy only the first word of a 16-byte nested value under both stages.
package aggregate_field_copy_test;
type pair = struct {
first: i64,
second: i64,
};
type outer = struct {
guard: i64,
value: pair,
tail: i64,
};
type nested = struct {
outer: outer,
};
let globalsource: outer;
let globaltarget: outer;
fn check(v: *outer, first: i64, second: i64) void = {
assert(v.value.first == first);
assert(v.value.second == second);
assert(v.guard == 91);
assert(v.tail == 92);
};
@test fn aggregate_field_memory_copy() void = {
let source: outer;
source.value.first = 11;
source.value.second = 12;
let target: outer;
target.guard = 91;
target.value.first = 1;
target.value.second = 2;
target.tail = 92;
target.value = source.value;
check(&target, 11, 12);
let pointer: *outer = ⌖
source.value.first = 21;
source.value.second = 22;
pointer.value = source.value;
check(&target, 21, 22);
let deep: nested;
deep.outer.value.first = 31;
deep.outer.value.second = 32;
target.value = deep.outer.value;
check(&target, 31, 32);
let indexed: [2]pair = [pair{first=5,second=6},
pair{first=35,second=36}];
target.value = indexed[1];
check(&target, 35, 36);
let pointed: pair = pair{first=37,second=38};
let sourcepointer: *pair = &pointed;
target.value = *sourcepointer;
check(&target, 37, 38);
globalsource.value.first = 41;
globalsource.value.second = 42;
globaltarget.guard = 91;
globaltarget.value.first = 3;
globaltarget.value.second = 4;
globaltarget.tail = 92;
globaltarget.value = globalsource.value;
check(&globaltarget, 41, 42);
};