Every section banner dies (103 -> 0) across test/lang, the observer suites, the C carriers, and the five comment-heavy corpus fixtures; banner provenance (#N cites, carrier numbers, repair-cluster labels) folded into headers or adjacent WHY comments. Narration deleted; row provenance, ref cites, divergence pins, and layout contracts kept (fwd-ref decl-order guards and bootstrap-gate corpus rationale restored where the sweep over-cut). Comment-only proven: all 3742 wwbuild workdir .s byte-identical before/after; test-commit and test-byteid (161 lang + 1399 data, 0 pinned-divergent) green.
56 lines
1.9 KiB
Plaintext
56 lines
1.9 KiB
Plaintext
// #63: let-init from an alias-NAMED struct
|
|
// LITERAL, migrated from test/wcc/944_alias_structlit_init_run.c (#5-C3).
|
|
// wwstage's cglet N_STRUCTLIT arm resolved the struct by a BARE
|
|
// structlookup(sname): for an alias `type rep2 = rep` only the base `rep` is
|
|
// registered, so the lookup returned nil and the field-fill never fired —
|
|
// <=8B silently zeroed the slot and DROPPED the literal, >8B loud-bailed.
|
|
// The fix routes the arm through structlookupchain (the #92/W2 SSoT), which
|
|
// chases the alias chain to the base struct; cstage was always correct via
|
|
// type_chase_named, so this is ww-only align-UP. The >24B sret RETURN twin
|
|
// (cgenstmt:1250) had no scalar-default catch and was silently wrong —
|
|
// reviewer-63 routed it through structlookupchain too (sret_return_alias32).
|
|
//
|
|
// The C driver ran each row on both stages + asserted cs==ww exit; here the
|
|
// cstage run is test-lang (T1) and the byte-id is test-lang-byteid (T2).
|
|
|
|
package alias_structlit_init_test;
|
|
|
|
type rep = struct { id: size };
|
|
type rep2 = rep;
|
|
type st = struct { a: size, b: size };
|
|
type row = st;
|
|
type pt2 = struct { a: size, b: size };
|
|
type big = struct { a: size, b: size, c: size, d: size };
|
|
type biga = big;
|
|
|
|
fn mk() biga = { return biga{a=1, b=2, c=3, d=4}; };
|
|
|
|
@test fn letinit_typed() void = {
|
|
let r: rep2 = rep2{id=6};
|
|
assert(r.id: int == 6);
|
|
};
|
|
|
|
@test fn letinit_untyped() void = {
|
|
let r = rep2{id=6};
|
|
assert(r.id: int == 6);
|
|
};
|
|
|
|
@test fn letlit_alias16() void = {
|
|
let a: row = row{a=3, b=4};
|
|
assert((a.a + a.b): int == 7);
|
|
};
|
|
|
|
// control: non-alias 16B let-init — the no-regress guard (the alias hop is
|
|
// the trigger).
|
|
@test fn control_direct() void = {
|
|
let x: pt2 = pt2{a=3, b=4};
|
|
assert((x.a + x.b): int == 7);
|
|
};
|
|
|
|
// the >24B sret-RETURN twin of the let-init site (cgenstmt:1250): the alias
|
|
// field-fill was SKIPPED and the callee returned an uninitialised sret buffer.
|
|
@test fn sret_return_alias32() void = {
|
|
let r: biga = mk();
|
|
assert((r.a + r.b + r.c + r.d): int == 10);
|
|
};
|