// nullable_try_test — #15 (F4): the `?` / `!` try operators on a nullable // `(*T|void)` operand must discriminate POINTER-vs-NULL, not tag-vs-success- // index. Migrated from test/wcc/949_nullable_try_run.c (non-abort value rows; // cs==ww byte-id rides T2). The must-abort-on-null polarity (`!` on null) stays // as a carrier (an abort cannot be a @test row). // // For a nullable operand AX holds the POINTER and successtag()=0, so pre-fix // wwstage cgtryprop/cgtryunw CMPQ'd $0,AX and treated NULL as success / a valid // pointer as the error (inverted). tryprop_valid pins the valid-ptr unwrap + // mutate; tryprop_null pins NULL propagates to the caller (pre-fix: null deref // SEGV); tryunw_valid pins the `!` valid-ptr unwrap. package nullable_try_test; fn gp(p: (*int|void)) (*int|void) = { let q = p?; *q = 7; return q; }; fn hu(p: (*int|void)) int = { let q = p!; return *q; }; @test fn tryprop_valid() void = { let x: int = 1; let r = gp(&x); assert(x == 7); }; @test fn tryprop_null() void = { let r = gp(void); let isvoid: bool = false; match (r) { case let q: *int => { }; case void => { isvoid = true; }; }; assert(isvoid); }; @test fn tryunw_valid() void = { let x: int = 42; assert(hu(&x): i32 == 42); };