test: migrate 933-939 str-cap family to test/lang @test
Fan out the str-cap read (933-936) and store (937-939) families into in-language @test files, following the 932 str_elem_cap template. Additive: the *_run.c stay in the C corpus (they are the only wwstage-runtime net for these cs==ww byte-id-blind shapes); de-dup deferred to fold 6. Per-shape @test fns, not a data table: each fn varies the codegen shape (base reg / chain depth / tuple return-ABI / store position), so the row-array idiom (blocked by #111) would lose coverage. Read family keeps the spoil()/register-clobber + junk==44 discrimination where the .c has it; store family pre-poisons the slot via a path distinct from the store under test. Asserts are primitives only.
This commit is contained in:
43
test/lang/str_chained_field_cap_test.ww
Normal file
43
test/lang/str_chained_field_cap_test.ww
Normal file
@@ -0,0 +1,43 @@
|
||||
// str_chained_field_cap_test — a CHAINED str-field read `o.p.f` (depth >= 2,
|
||||
// where p is a *struct field of o and f is a str field of *p) must load the
|
||||
// full 24B {ptr,len,cap} header, not just {ptr,len}, migrated from
|
||||
// test/wcc/934_str_chained_field_cap_run.c (C4.6 case B). str is 24B since
|
||||
// Phase 2 (#1); pre-caseB the chained *struct N_DOT str arm loaded 2 words (ptr
|
||||
// in AX, len in BX) and dropped cap. The miscompile was cs==ww, so the 990-997
|
||||
// byte-id gates stayed GREEN while the runtime was wrong — behavioral @test is
|
||||
// the net. This is the chained sibling of str_field_cap_test (direct/single-
|
||||
// deref S1/S2): the lhs cgexpr leaves AX = the inner *struct pointer, then the
|
||||
// field is read off AX, cap from +16(AX), base (AX = ptr) read LAST.
|
||||
//
|
||||
// DISCRIMINATION: a 2-word read leaves CX untouched, so the row could
|
||||
// coincidentally pass if CX happened to still carry the poison cap. spoil()
|
||||
// interposes a CX-clobbering call between the field store and the chained read
|
||||
// (its own str copy leaves cap=44 in CX), so a broken read observes 44 not 8.
|
||||
|
||||
package str_chained_field_cap_test;
|
||||
|
||||
type inr = struct { f: str };
|
||||
type otr = struct { p: *inr };
|
||||
|
||||
fn spoil() i32 = {
|
||||
let z: str = "zzzz";
|
||||
z.cap = 44i32;
|
||||
let w: str = z;
|
||||
return w.cap: i32;
|
||||
};
|
||||
|
||||
@test fn caseb_chained_field() void = {
|
||||
// `o.p.f`: o a struct holding p: *inr, inr holding str field f. Poison
|
||||
// cap=8 (len=2).
|
||||
let p: str = "hi";
|
||||
p.cap = 8i32;
|
||||
let ist: inr;
|
||||
ist.f = p;
|
||||
let o: otr;
|
||||
o.p = &ist;
|
||||
let junk: i32 = spoil();
|
||||
let s: str = o.p.f;
|
||||
assert(s.cap: i32 == 8);
|
||||
assert(s.len: i32 == 2);
|
||||
assert(junk == 44);
|
||||
};
|
||||
Reference in New Issue
Block a user