wcc/ww: compound OP= on a tagged index/ident is a loud reject (#20/#21)
Compound `OP=` through an index (gs[i]/a[i]) or a bare ident (g) on a tagged union silently misbehaved: cstage dropped the index compound and plain-stored, and BOTH stages compiled an ident compound into an add on the tag word -- byte-identical, so the gate stayed green while the tag was corrupted. A compound op on a whole union is nonsense. Gate the index plain-store arm on TK_ASSIGN so a compound falls to the existing #133 reject (wwstage's byte-id twin); add a dedicated #21 ident reject in both stages. This closes the compound half of the tagged-payload write class (deref #18, dot #34 already reject). #19 (global tagged-array static-init DATA) is a separate emitter, still open.
This commit is contained in:
@@ -31677,6 +31677,25 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
};
|
||||
};
|
||||
};
|
||||
// #21: a COMPOUND op on a whole tagged-union IDENT (`g OP= v`
|
||||
// with g:(int|bool)) is nonsense — the ident load-combine-store
|
||||
// tail below reads and writes one word of the {payload,tag} box,
|
||||
// corrupting the tag. Reject loud here, the ident twin of the #18
|
||||
// deref / #133 index rejects; the byte-id twin of the cstage
|
||||
// guard. Plain `=` (the tagged-ident reassign arm just below) is
|
||||
// untouched.
|
||||
if (lhs != nil) {
|
||||
if (lhs.kind == nkind.N_IDENT && n.op != tkind.TK_ASSIGN) {
|
||||
let itu: *tinfo = tichase(lhs.type_: *tinfo);
|
||||
if (itu != nil) {
|
||||
if (itu.kind == tykind.TY_TAGGED) {
|
||||
let m21: str = "ident compound on tagged not wired (#21/rule-7)\n";
|
||||
os.write(2, m21.ptr, m21.len: u64);
|
||||
os.exit(1);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
// Tagged-union local reassignment: `r = expr;` where r has a
|
||||
// tagged-union type. Delegate to cgwidentaggedstore (same path
|
||||
// as cglet's tagged-init). Covers nullable fold, tagged source,
|
||||
|
||||
@@ -8331,6 +8331,25 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
};
|
||||
};
|
||||
};
|
||||
// #21: a COMPOUND op on a whole tagged-union IDENT (`g OP= v`
|
||||
// with g:(int|bool)) is nonsense — the ident load-combine-store
|
||||
// tail below reads and writes one word of the {payload,tag} box,
|
||||
// corrupting the tag. Reject loud here, the ident twin of the #18
|
||||
// deref / #133 index rejects; the byte-id twin of the cstage
|
||||
// guard. Plain `=` (the tagged-ident reassign arm just below) is
|
||||
// untouched.
|
||||
if (lhs != nil) {
|
||||
if (lhs.kind == nkind.N_IDENT && n.op != tkind.TK_ASSIGN) {
|
||||
let itu: *tinfo = tichase(lhs.type_: *tinfo);
|
||||
if (itu != nil) {
|
||||
if (itu.kind == tykind.TY_TAGGED) {
|
||||
let m21: str = "ident compound on tagged not wired (#21/rule-7)\n";
|
||||
os.write(2, m21.ptr, m21.len: u64);
|
||||
os.exit(1);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
// Tagged-union local reassignment: `r = expr;` where r has a
|
||||
// tagged-union type. Delegate to cgwidentaggedstore (same path
|
||||
// as cglet's tagged-init). Covers nullable fold, tagged source,
|
||||
|
||||
@@ -31677,6 +31677,25 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
};
|
||||
};
|
||||
};
|
||||
// #21: a COMPOUND op on a whole tagged-union IDENT (`g OP= v`
|
||||
// with g:(int|bool)) is nonsense — the ident load-combine-store
|
||||
// tail below reads and writes one word of the {payload,tag} box,
|
||||
// corrupting the tag. Reject loud here, the ident twin of the #18
|
||||
// deref / #133 index rejects; the byte-id twin of the cstage
|
||||
// guard. Plain `=` (the tagged-ident reassign arm just below) is
|
||||
// untouched.
|
||||
if (lhs != nil) {
|
||||
if (lhs.kind == nkind.N_IDENT && n.op != tkind.TK_ASSIGN) {
|
||||
let itu: *tinfo = tichase(lhs.type_: *tinfo);
|
||||
if (itu != nil) {
|
||||
if (itu.kind == tykind.TY_TAGGED) {
|
||||
let m21: str = "ident compound on tagged not wired (#21/rule-7)\n";
|
||||
os.write(2, m21.ptr, m21.len: u64);
|
||||
os.exit(1);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
// Tagged-union local reassignment: `r = expr;` where r has a
|
||||
// tagged-union type. Delegate to cgwidentaggedstore (same path
|
||||
// as cglet's tagged-init). Covers nullable fold, tagged source,
|
||||
|
||||
Reference in New Issue
Block a user