w6c+w6c_ww: (*p)[i] deref base materializes the array ADDRESS (#61 C)
Both stages SEGV'd identically (byte-id-blind): cgun's TK_STAR emitted a scalar MOVQ (AX),AX for an array pointee, so the index consumed a[0]'s VALUE as its base — a wild deref. An array value IS its address everywhere in this cgen (#270-1a), so the ARRAY pointee now takes the same skip as the #185 *fn deref in both stages: `*p` leaves AX = p's value, and every consumer that materializes a complex index base via cgexpr(base) — N_INDEX read fallback, cgassign store/compound, TK_AMP, N_SLICE — gets the array address from the one deref choke-point. wwstage additionally joins the N_UN-TK_STAR base to the stamped-tinfo esz arms (cgindex / cgassign store + compound / TK_AMP &(*p)[i]) where cstage reads base->type uniformly: without it, esz fell to the 8B default and a narrow element would mis-stride the moment the base started materializing (cs!=ww only reachable post-choke-point-fix, which is why it rides this commit). 949_ptrarr_index_run grows the deref_* rows: read (8B/4B/param-base), write (8B / 1B+neighbor-guards), compound — runtime + byte-id, the only nets that can see a both-stages-identical miscompile.
This commit is contained in:
@@ -32,6 +32,18 @@
|
||||
* param / local / cast bases, read / write / compound routes,
|
||||
* neighbor-corruption guards, the &p[i] pointer-difference (B), and
|
||||
* the live consumer's mix-in-place shape (siphash round).
|
||||
*
|
||||
* C. `(*p)[i]` explicit deref + index — BOTH stages SEGV'd
|
||||
* identically (byte-id-blind): cgun's TK_STAR materialized an
|
||||
* 8-byte SCALAR load of a[0]'s value and the index used that
|
||||
* VALUE as its base — a wild deref. Fixed in both stages at the
|
||||
* deref choke-point: an ARRAY pointee takes the #185 *fn skip
|
||||
* (an array value IS its address, #270-1a), so `*p` leaves AX =
|
||||
* p's value and every index/addr-of/store route through
|
||||
* `cgexpr(base)` materializes the array address for free. The
|
||||
* deref_* rows pin read / write / compound at 8B and narrow
|
||||
* widths (the narrow rows also pin the wwstage N_UN-base
|
||||
* stamped-tinfo esz arm against the 8B default).
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -261,6 +273,60 @@ static const struct row rows[] = {
|
||||
" if (v[3] != 11u64) { return 4; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0 },
|
||||
/* C: (*p)[i] read, 8B elem (ken p7 — SEGV'd both stages). */
|
||||
{ "deref_rd_u64",
|
||||
"package main;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let a: [4]u64 = [100u64, 101u64, 102u64, 103u64];\n"
|
||||
" let p: *[4]u64 = &a;\n"
|
||||
" return (*p)[1]: i32;\n"
|
||||
"};\n", 101 },
|
||||
/* C: (*p)[i] read, 4B elem — pins the N_UN-base esz arm (the 8B
|
||||
* default would mis-stride once the base materializes). */
|
||||
{ "deref_rd_u32",
|
||||
"package main;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let a: [4]u32 = [11u32, 22u32, 33u32, 44u32];\n"
|
||||
" let p: *[4]u32 = &a;\n"
|
||||
" return (*p)[2]: i32;\n"
|
||||
"};\n", 33 },
|
||||
/* C: (*p)[i] read through a param base. */
|
||||
{ "deref_rd_param",
|
||||
"package main;\n"
|
||||
"fn rd(p: *[4]u64) u64 = {\n"
|
||||
" return (*p)[1];\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let a: [4]u64 = [100u64, 101u64, 102u64, 103u64];\n"
|
||||
" return rd(&a): i32;\n"
|
||||
"};\n", 101 },
|
||||
/* C: (*p)[i] write, 8B elem. */
|
||||
{ "deref_wr_u64",
|
||||
"package main;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let a: [4]u64 = [1u64, 2u64, 3u64, 4u64];\n"
|
||||
" let p: *[4]u64 = &a;\n"
|
||||
" (*p)[1] = 7u64;\n"
|
||||
" return (a[0] + a[1] + a[2]): i32;\n"
|
||||
"};\n", 11 },
|
||||
/* C: (*p)[i] write, 1B elem, neighbor guards. */
|
||||
{ "deref_wr_u8",
|
||||
"package main;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let a: [4]u8 = [1u8, 2u8, 3u8, 4u8];\n"
|
||||
" let p: *[4]u8 = &a;\n"
|
||||
" (*p)[1] = 9u8;\n"
|
||||
" return (a[0] + a[1] + a[2]): i32;\n"
|
||||
"};\n", 13 },
|
||||
/* C: (*p)[i] compound. */
|
||||
{ "deref_compound_u64",
|
||||
"package main;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let a: [4]u64 = [100u64, 101u64, 102u64, 103u64];\n"
|
||||
" let p: *[4]u64 = &a;\n"
|
||||
" (*p)[1] += 5u64;\n"
|
||||
" return a[1]: i32;\n"
|
||||
"};\n", 106 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user