The arr[i].f=mk() assign arm had no aggregate-field sub-arm, so a by-value aggregate field receive fell to the scalar default (one MOVQ, dropping DX/CX) — silent on BOTH stages (byte-id blind). Add a dual-site symmetric in-cap N_CALL arm mirroring C2c (c83a340): scratch-first materialise AX/DX/CX, then word-copy to (fi.foff+k*8) within &arr[i], sizing from the natural field size fi.fsz (not slotsize). Rule-7 LOUD-STOP for the three cases the in-cap GP path cannot transport: over-cap sret (#11c/#234), a float-bearing field whose eightbyte classifies SSE (#11/#165), and a 3/5/6/7-byte sub-8 tail the single narrow tail MOV cannot express (the general cascade tail is the shared C2c/#11 follow-up, task #10). Value-asserting pins (poison-seeded, redden under each stage's independent revert) plus cfail pins for the three loud-stops.
Contained to the indexed base + in-cap call rhs; arr[i].f=src (#11b) and over-cap (#11c) are separate.
15 lines
575 B
Plaintext
15 lines
575 B
Plaintext
//ww:error "float-bearing aggregate field receive"
|
|
// #11/#165 tripwire: an in-cap aggregate-returning CALL into a FLOAT-bearing
|
|
// aggregate field of an indexed element. The return routes a float eightbyte to
|
|
// X0/X1, which the GP AX/DX/CX materialise cursor cannot read -> both stages
|
|
// LOUD-STOP (#171). SUCCESS = the float guard regressed to silent GP-garbage.
|
|
package main;
|
|
type ft = struct { x: f64, y: i64 };
|
|
type sf = struct { f: ft, g: i64 };
|
|
fn mk() ft = { return ft{x=1.5f64, y=7i64}; };
|
|
export fn main() i32 = {
|
|
let arr: [2]sf;
|
|
arr[1].f = mk();
|
|
return 0;
|
|
};
|