wcc/cgen: GAP-A.ptr global-array base — LEAQ name(SB) not (BP) (#11, both stages)
A global fixed array's .ptr (= &A[0]) must take the SB base, but cstage emitted frame-relative LEAQ off(BP) for BOTH let- and def-global arrays -> *A.ptr read frame garbage (0 instead of the element). cstage-SILENT; wwstage def-global was a loud link-error. The .ptr read arm now gates off==0 && (let_islet || def_isarraydef) -> LEAQ name(SB), reusing the def-array index base predicate (cgen.c:4367, the #94/#231/#48 class). Locals (off != 0) stay BP-relative -- the 14 toolchain backing-ptr sites unaffected. wwstage let-global was already correct; this adds the missing def-global arm (cgenexpr.ww), converging cstage/wwstage byte-identical across all three flavors (local / let-global / def-global) and closing a latent cstage-only let-global cs!=ww divergence. Byte-id 990-997 8/8 (corpus has no global .ptr); w6c/w6c_ww binaries move (cgen changed). test/wcc/818 table-driven, build+run+byte-id per flavor.
This commit is contained in:
@@ -11123,7 +11123,21 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
break;
|
||||
}
|
||||
if (ptrfld) {
|
||||
ins2(c, A_LEAQ, amem(D_BP, off), areg(D_AX));
|
||||
/* The array's backing pointer = address of its
|
||||
* element 0 (array.ptr ≡ &A[0], drew #13). A LOCAL
|
||||
* array IS its frame slot — LEAQ off(BP). A module
|
||||
* GLOBAL (let or def array) lives at name(SB): off==0
|
||||
* here would LEAQ the frame's first slot = garbage
|
||||
* (*p→0), the GAP-A.ptr silent miscompile. Same
|
||||
* off==0/global base-selection as the def-array index
|
||||
* base (cgen.c:4367) and #231/#48. */
|
||||
if (off == 0 && (let_islet(n->lhs->str)
|
||||
|| def_isarraydef(n->lhs->str)))
|
||||
ins2(c, A_LEAQ, masym(c, n->lhs->str),
|
||||
areg(D_AX));
|
||||
else
|
||||
ins2(c, A_LEAQ, amem(D_BP, off),
|
||||
areg(D_AX));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user