test: 954 add struct-exclusion control row (#102 over-catch guard)
The fix's new cglet branch is gated on sz==16 AND rettupleof != nil. The
existing rows prove it CATCHES 16B tuple receives but nothing pinned that
it does NOT catch a 16B struct{i64,i64} receive (same sz==16, but
rettupleof returns nil for a non-tuple return). A future rettupleof
refactor returning non-nil for a struct would silently route the struct
through the AX/DX tuple spill and miscompile it, gate-blind. The new
ctl_struct row is byte-id and runs correctly (exit 12) both pre- and
post-fix, pinning the tuple/struct discrimination.
This commit is contained in:
@@ -28,10 +28,16 @@
|
|||||||
* diverge by exactly one dropped `MOVQ DX, -8(BP)`; post-fix all
|
* diverge by exactly one dropped `MOVQ DX, -8(BP)`; post-fix all
|
||||||
* are byte-identical.
|
* are byte-identical.
|
||||||
*
|
*
|
||||||
* Two CONTROL rows pin that the fix touches nothing else: the
|
* Three CONTROL rows pin that the fix touches nothing else: the
|
||||||
* destructure form `let (a,b) = mk()` (cgmlet + tupstore cursor) and a
|
* destructure form `let (a,b) = mk()` (cgmlet + tupstore cursor), a
|
||||||
* 32B wide/str-element single-var tuple stay byte-id both pre- and
|
* 32B wide/str-element single-var tuple, and a 16B struct{i64,i64}
|
||||||
* post-fix (the fix is in cglet/N_LET, gated on sz==16).
|
* single-var receive — all stay byte-id both pre- and post-fix. The fix
|
||||||
|
* is in cglet/N_LET, gated on sz==16 AND rettupleof != nil; the struct
|
||||||
|
* row is the over-catch guard: sz IS 16 but rettupleof returns nil for a
|
||||||
|
* non-tuple return, so the new branch must NOT hijack the struct's
|
||||||
|
* generic store. Without that guard a struct receive would route through
|
||||||
|
* the AX/DX tuple spill and miscompile any struct whose layout differs
|
||||||
|
* from {word0,word1}.
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -110,6 +116,20 @@ static const struct row rows[] = {
|
|||||||
"\tlet t: (i64, str) = mk();\n"
|
"\tlet t: (i64, str) = mk();\n"
|
||||||
"\treturn t.0: i32;\n"
|
"\treturn t.0: i32;\n"
|
||||||
"};\n", 7 },
|
"};\n", 7 },
|
||||||
|
/* CONTROL — over-catch guard. A 16B struct{i64,i64} from-call receive
|
||||||
|
* is sz==16 like the bug rows, but rettupleof returns nil for a
|
||||||
|
* non-tuple return, so the fix's new branch must NOT hijack it; it
|
||||||
|
* stays on the generic struct store and byte-id pre- and post-fix.
|
||||||
|
* Pins that the fix's tuple/struct discrimination (#102) holds. a=5,
|
||||||
|
* b=7, 5+7 = 12. */
|
||||||
|
{ "ctl_struct",
|
||||||
|
"package main;\n"
|
||||||
|
"type pair = struct { a: i64, b: i64 };\n"
|
||||||
|
"fn mk() pair = { return pair { a = 5, b = 7 }; };\n"
|
||||||
|
"export fn main() i32 = {\n"
|
||||||
|
"\tlet t = mk();\n"
|
||||||
|
"\treturn (t.a: i32) + (t.b: i32);\n"
|
||||||
|
"};\n", 12 },
|
||||||
{ NULL, NULL, 0 }
|
{ NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user