nx_probe_ptrfield_idx.nx source
↩ module page · 104 lines · 5282 B
1// nx_probe_ptrfield_idx.nx -- MINIMAL REPRO for debt 1786057660.
2//
3// CLAIM UNDER TEST: nx_cc miscompiles `structptr.field[i]` when `field` is a pointer to a
4// NON-BYTE type. Isolated by differential bisect in nx_linemap.nx (three *i64 fields); this
5// probe strips that finding to the smallest shape that can still exhibit it, so the verdict
6// is about the LANGUAGE FEATURE and not about the line map.
7//
8// The estate's existing instance of the pattern is ctx.out[pos] in nx_import.nx, where the
9// field is *u8 -- element size 1, so an element-size scaling error is invisible BY
10// CONSTRUCTION. Every other *i64 indexing site nearby (canonicalise_path) uses a LOCAL
11// handle. So the codebase avoided this shape by accident, not by design, and nothing tests it.
12//
13// Exit codes name the exact failing direction rather than a single boolean:
14// 0 = no defect: field-index and hoisted-local addressing agree, both directions
15// 11 = write-via-field / read-via-local disagreed at index 0 (base or scale wrong)
16// 12 = ... at index 1 (index 0 agreeing but 1 not => SCALE, not base)
17// 13 = ... at index 2
18// 14 = write-via-local / read-via-field disagreed (the reverse direction)
19// 15 = *u8 control FAILED -- if this fires the defect is broader than non-byte pointers
20// and the whole diagnosis in 1786057660 needs rewriting
21
22import "nx_syscalls.nx"
23const K_MAGIC_1111: i64 = 1111
24const K_MAGIC_2222: i64 = 2222
25const K_MAGIC_3333: i64 = 3333
26const K_MAGIC_4444: i64 = 4444
27const K_MAGIC_5555: i64 = 5555
28const K_MAGIC_6666: i64 = 6666
29const K_MAGIC_23331: i64 = 23331
30
31struct PfHolder {
32 arr: *i64,
33 barr: *u8,
34 n: i64,
35}
36
37// An instrument whose ONLY output channel is its exit code is unreadable through a harness
38// that reports a pid (nx_job_run does exactly that). Say the verdict out loud.
39func pf_say(s: *u8) -> i64 {
40 var n: i64 = 0
41 while s[n] != 0 { n = n + 1 }
42 sys_write(1, s, n)
43 return 0
44}
45
46func main() -> i64 {
47 let raw: *u8 = sys_mmap(64)
48 let h: *PfHolder = raw as *PfHolder
49 h.arr = sys_mmap(8 * 64) as *i64
50 h.barr = sys_mmap(64)
51 h.n = 0
52
53 // WRITE through the struct field index -- the suspect shape.
54 h.arr[0] = K_MAGIC_1111
55 h.arr[1] = K_MAGIC_2222
56 h.arr[2] = K_MAGIC_3333
57
58 // READ through a hoisted local handle -- the known-good shape.
59 let a: *i64 = h.arr
60 if a[0] != K_MAGIC_1111 { pf_say("PTRFIELD verdict=DEFECT at=idx0 dir=write-field/read-local -- base or scale wrong\n" as *u8); return 11 }
61 if a[1] != K_MAGIC_2222 { pf_say("PTRFIELD verdict=DEFECT at=idx1 dir=write-field/read-local -- idx0 agreed so SCALE, not base\n" as *u8); return 12 }
62 if a[2] != K_MAGIC_3333 { pf_say("PTRFIELD verdict=DEFECT at=idx2 dir=write-field/read-local\n" as *u8); return 13 }
63
64 // Reverse direction: write through the local, read through the field index.
65 a[3] = K_MAGIC_4444
66 if h.arr[3] != K_MAGIC_4444 { pf_say("PTRFIELD verdict=DEFECT at=idx3 dir=write-local/read-field\n" as *u8); return 14 }
67
68 // CONTROL: the *u8 case, which the estate already relies on heavily (ctx.out[pos]).
69 // It MUST pass. If it does not, the defect is not specific to non-byte element types
70 // and this probe has refuted its own framing -- which is worth knowing immediately.
71 h.barr[0] = 7 as u8
72 let b: *u8 = h.barr
73 if b[0] != (7 as u8) { pf_say("PTRFIELD verdict=FRAMING-REFUTED -- the *u8 control FAILED, so the defect is NOT specific to non-byte element types; rewrite the diagnosis in debt 1786057660\n" as *u8); return 15 }
74
75 // ---- ROUND 2 -------------------------------------------------------------
76 // Round 1 (constant indices) came back NO-DEFECT and thereby REFUTED the first
77 // diagnosis in debt 1786057660. Re-reading the RED-vs-GREEN diff showed why the
78 // probe was blind: the hoist changed TWO things, not one. It hoisted the pointer
79 // AND the index. The real shape in nx_linemap was `lm.span_out[lm.n_spans]` --
80 // a field pointer subscripted by a FIELD VALUE. Round 1 only ever wrote
81 // `h.arr[0]`, a constant. The untested combination was the whole finding.
82 h.n = 5
83 h.arr[h.n] = K_MAGIC_5555
84 if a[5] != K_MAGIC_5555 { pf_say("PTRFIELD verdict=DEFECT at=idx5 dir=write-field[field]/read-local -- FIELD-VALUE SUBSCRIPT is the defect, not the field pointer\n" as *u8); return 16 }
85
86 h.n = 6
87 a[6] = K_MAGIC_6666
88 if h.arr[h.n] != K_MAGIC_6666 { pf_say("PTRFIELD verdict=DEFECT at=idx6 dir=write-local/read-field[field] -- FIELD-VALUE SUBSCRIPT on the READ side\n" as *u8); return 17 }
89
90 // And the loop-condition shape from lm_lookup: `while i < lm.n_spans`, comparing
91 // against a field re-read every iteration while the body subscripts a field pointer.
92 h.n = 8
93 var i: i64 = 0
94 var sum: i64 = 0
95 while i < h.n {
96 sum = sum + h.arr[i]
97 i = i + 1
98 }
99 // arr[0..7] = 1111,2222,3333,4444,0,5555,6666,0 -> 23331
100 if sum != K_MAGIC_23331 { pf_say("PTRFIELD verdict=DEFECT at=loop dir=field-bound-loop-over-field-ptr\n" as *u8); return 18 }
101
102 pf_say("PTRFIELD verdict=NO-DEFECT -- constant AND field-value subscripts agree with hoisted locals in both directions; *u8 control passed; field-bounded loop summed correctly\n" as *u8)
103 return 0
104}