test: migrate 944_alias_def_addr to @test + runww reject, retire C twin (fold-3)
#88 alias/def/address-of family: 5 value rows -> test/lang/alias_def_addr_test.ww (primitive-only asserts), 1 reject (str-def-non-addressable, shared body 'cannot take address of non-addressable def') -> runww //ww:error dual-stage carrier. byteid floor 53->54.
This commit is contained in:
70
test/lang/alias_def_addr_test.ww
Normal file
70
test/lang/alias_def_addr_test.ww
Normal file
@@ -0,0 +1,70 @@
|
||||
// alias_def_addr_test — address-of a def whose declared type is an ALIAS of
|
||||
// an array/struct (#5 alias arc F2a, task #88), migrated from
|
||||
// test/wcc/944_alias_def_addr_run.c. defisaddressable (cgen.ww) keyed the
|
||||
// array leg on the UNCHASED syntactic dtnode (N_TARRAY), so `&D` where D is a
|
||||
// def typed as an ALIAS of an array missed the gate and fell to the rule-7
|
||||
// loud "non-addressable def" tail — even though the def-array DATA emitter
|
||||
// already peels TY_NAMED transitively, so the alias def HAS a DATA symbol.
|
||||
// The gate-only fix (tichase(dtn.type_) == TY_ARRAY) restores gate ==
|
||||
// emission set; cstage (def_isarraydef over the chased let_isarray) is the
|
||||
// runtime-correct reference. Pre-fix: def_l1/def_l2/def_order ww LOUD, cs 0.
|
||||
// These rows are the #88 ASM-FRAGILE surface (&def / alias-of-addr is exactly
|
||||
// where cs!=ww surfaces) — T2 keeps cs==ww. The non-addressable str def
|
||||
// (`&S`, no DATA symbol) STAYS a loud rule-7 reject and is the runww carrier
|
||||
// (test/wcc/data/alias_def_addr_nonaddr). PRIMITIVE-only asserts (readback
|
||||
// through the &-derived pointer is the pin — a wrong address or wrong DATA
|
||||
// emission yields a wrong readback; no fmt/strconv in any assert path).
|
||||
// def_l2's readback casts to the BASE array ptr before the deref-index: the
|
||||
// natural `(*p)[2]` over a 2-LEVEL-alias pointee trips a SEPARATE pre-existing
|
||||
// cstage double-deref (task #93), deliberately not exercised here.
|
||||
|
||||
package alias_def_addr_test;
|
||||
|
||||
// def_ctrl — plain [3]int def, no alias; the always-held control.
|
||||
def Dctrl: [3]int = [1000: int, 2000: int, 3000: int];
|
||||
|
||||
@test fn alias_def_addr_ctrl() void = {
|
||||
let p: *[3]int = &Dctrl;
|
||||
assert((*p)[2] == 3000);
|
||||
};
|
||||
|
||||
// def_l1 — 1-level alias def array; &D missed the unchased gate pre-fix.
|
||||
type arr1 = [3]int;
|
||||
def Dl1: arr1 = [1000: int, 2000: int, 3000: int];
|
||||
|
||||
@test fn alias_def_addr_l1() void = {
|
||||
let p: *arr1 = &Dl1;
|
||||
assert((*p)[2] == 3000);
|
||||
};
|
||||
|
||||
// def_l2 — 2-level alias; readback casts to the BASE array ptr (task #93).
|
||||
type arr2a = [3]int;
|
||||
type arr2b = arr2a;
|
||||
def Dl2: arr2b = [1000: int, 2000: int, 3000: int];
|
||||
|
||||
@test fn alias_def_addr_l2() void = {
|
||||
let p: *arr2b = &Dl2;
|
||||
let q: *[3]int = p: *[3]int;
|
||||
assert((*q)[2] == 3000);
|
||||
};
|
||||
|
||||
// def_order — the alias type is declared AFTER the def that uses it.
|
||||
def Dord: arrord = [1000: int, 2000: int, 3000: int];
|
||||
|
||||
@test fn alias_def_addr_order() void = {
|
||||
let p: *arrord = &Dord;
|
||||
assert((*p)[2] == 3000);
|
||||
};
|
||||
|
||||
type arrord = [3]int;
|
||||
|
||||
// def_struct — alias-typed STRUCT def; defvarstructinfo already chased
|
||||
// aliaslookup transitively, so this leg held before and after (PREMISE-5).
|
||||
type pt = struct { x: int, y: int };
|
||||
type pt2 = pt;
|
||||
def Dstruct: pt2 = pt2{x = 1000, y = 2000};
|
||||
|
||||
@test fn alias_def_addr_struct() void = {
|
||||
let p: *pt2 = &Dstruct;
|
||||
assert(p.y == 2000);
|
||||
};
|
||||
Reference in New Issue
Block a user