w6c: tagged GLOBAL reassign emits the store
cstage silently dropped the store on reassigning a module-global tagged union; mirror the landed wwstage emission (tag+payload to g(SB) via the widener). Closes the cs half of the F8 #263 pair; the repro row flips to cs==ww==correct. Task #41.
This commit is contained in:
@@ -3,29 +3,20 @@
|
||||
* module-GLOBAL tagged-union ident (`g = expr`) must store the new tag and
|
||||
* payload, not clobber only one word.
|
||||
*
|
||||
* THE BUG (cat-A silent miscompile, #263 BOTH-WRONG): cgenexpr.ww cgassign's
|
||||
* tagged-union reassignment arm delegated to cgwidentaggedstore ONLY for a
|
||||
* LOCAL ident (localfindnode != nil). A module-global tagged ident (lc==nil)
|
||||
* had no arm and fell through to the generic scalar store, which wrote one
|
||||
* word into the tag slot and left the payload stale. cstage is ALSO wrong:
|
||||
* it drops the store entirely (the new value never reaches g) — so the repro
|
||||
* is cs≠ww residual until the cstage half lands (ww-core TASK #41).
|
||||
* THE BUG (cat-A silent miscompile, #263 BOTH-WRONG, now CLOSED both stages):
|
||||
* cgassign's tagged-union reassignment arm delegated to the widener ONLY for a
|
||||
* LOCAL ident. A module-global tagged ident had no arm and fell through to the
|
||||
* generic scalar store (wwstage clobbered the tag word; cstage dropped the
|
||||
* store entirely). The ww half landed in F8-c5; the cstage half (LEAQ g(SB),BX
|
||||
* then cg_widen_tagged_store off BX) landed in ww-core TASK #41 — both stages
|
||||
* now store the full box and the .s is byte-identical.
|
||||
*
|
||||
* THE WWSTAGE FIX (ww-runtime-correct): add the lc==nil arm — LEAQ g(SB),BX
|
||||
* then cgwidentaggedstore stores tag+payload off BX (mirrors the local arm
|
||||
* and the global-struct-field tagged arm). ww now stores the full box.
|
||||
* cstage stays wrong → the rows assert ww-correct AND pin cstage's
|
||||
* documented-wrong value (store dropped → g keeps its init), so the residual
|
||||
* is never misread as a regression.
|
||||
*
|
||||
* Rows (per-driver expected — want_cs / want_ww):
|
||||
* row | shape | cs | ww
|
||||
* ----------------+----------------------------------------+----+----
|
||||
* reassign_i64 | g:(i64|void)=0; g=7; match i64 | 0 | 7
|
||||
* reassign_str | g:(str|i64)=0; g="hello"; match str→len | 88 | 5
|
||||
* reassign_union | g:(i64|bool)=0; g=5; match i64 | 0 | 5
|
||||
* (cstage drops the store → g keeps its init → the i64/void/i64-tag arm;
|
||||
* #41 closes the cs side, at which point these become cs==ww.)
|
||||
* Rows (cs==ww after the cstage half landed):
|
||||
* row | shape | exit
|
||||
* ----------------+----------------------------------------+-----
|
||||
* reassign_i64 | g:(i64|void)=0; g=7; match i64 | 7
|
||||
* reassign_str | g:(str|i64)=0; g="hello"; match str→len | 5
|
||||
* reassign_union | g:(i64|bool)=0; g=5; match i64 | 5
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -61,7 +52,7 @@ static const struct row rows[] = {
|
||||
" case void => return 99;\n"
|
||||
" };\n"
|
||||
"};\n",
|
||||
0, 7 },
|
||||
7, 7 },
|
||||
|
||||
{ "reassign_str",
|
||||
"package main;\n"
|
||||
@@ -73,7 +64,7 @@ static const struct row rows[] = {
|
||||
" case i64 => return 88;\n"
|
||||
" };\n"
|
||||
"};\n",
|
||||
88, 5 },
|
||||
5, 5 },
|
||||
|
||||
{ "reassign_union",
|
||||
"package main;\n"
|
||||
@@ -85,7 +76,7 @@ static const struct row rows[] = {
|
||||
" case bool => return 77;\n"
|
||||
" };\n"
|
||||
"};\n",
|
||||
0, 5 },
|
||||
5, 5 },
|
||||
};
|
||||
|
||||
/* run_build — build+run `src` via `driver`; returns the binary's exit
|
||||
|
||||
Reference in New Issue
Block a user