wcc/cgen: loud-align static-global tagged cast-init (wwstage align to cstage)
A module-global tagged init via cast (`let g: u = true: u;`) silently emitted tag=0; cstage louds. Route emittaggeddata through flatvariantidx (the cstage cg_tag_for_variant twin) so an unsupported variant louds while valid str/slice cast-inits still accept+run. test/wcc/838.
This commit is contained in:
@@ -41336,7 +41336,22 @@ fn emittaggeddata(c: *cgen, name: str, module: str, tt: *node, rhs: *node, sz: i
|
||||
let r: *node = rhs;
|
||||
for (r != nil && r.kind == nkind.N_CAST) { r = r.lhs; };
|
||||
if (r == nil) { return false; };
|
||||
let tag: i32 = taggedvariantindex(c, tt, r);
|
||||
// E8/#35: select the variant via flatvariantidx — the EXACT twin of
|
||||
// cstage emit_tagged_data's cg_tag_for_variant (cmd/w6c/cgen.c:15472).
|
||||
// taggedvariantindex adds a str/slice SHAPE fallback (cgenutil.ww:3054)
|
||||
// that cstage does NOT run at this site: a same-type/subset CAST init
|
||||
// (`let g: u = true: u;`) stamps the peeled literal's type_ as the
|
||||
// union itself, so flatvariantidx finds no variant and returns -1,
|
||||
// matching cstage's loud (caller emits "unsupported variant init",
|
||||
// cgen.ww:2818). The shape fallback instead picked the first scalar
|
||||
// variant (tag 0) -> SILENT miscompile (ran the int arm on a bool
|
||||
// value, the S1 coincidence trap). A bare-literal init (`= true` / `=
|
||||
// 7`) keeps its concrete/untyped type and still resolves via
|
||||
// flatvariantidx pass 1 (byte-id with cstage); a str-literal CAST
|
||||
// (`"hi": u`) keeps its str type and resolves to the str variant too.
|
||||
// Faithful tag-remap for a cast-init static global = the deferred
|
||||
// #23/#40 nominal widen feature.
|
||||
let tag: i32 = flatvariantidx(c, tt, r);
|
||||
if (tag < 0) { return false; };
|
||||
let wide: bool = nodeisstr(c, r) || nodeisslice(c, r);
|
||||
let i: i32 = 0;
|
||||
|
||||
@@ -2473,7 +2473,22 @@ fn emittaggeddata(c: *cgen, name: str, module: str, tt: *node, rhs: *node, sz: i
|
||||
let r: *node = rhs;
|
||||
for (r != nil && r.kind == nkind.N_CAST) { r = r.lhs; };
|
||||
if (r == nil) { return false; };
|
||||
let tag: i32 = taggedvariantindex(c, tt, r);
|
||||
// E8/#35: select the variant via flatvariantidx — the EXACT twin of
|
||||
// cstage emit_tagged_data's cg_tag_for_variant (cmd/w6c/cgen.c:15472).
|
||||
// taggedvariantindex adds a str/slice SHAPE fallback (cgenutil.ww:3054)
|
||||
// that cstage does NOT run at this site: a same-type/subset CAST init
|
||||
// (`let g: u = true: u;`) stamps the peeled literal's type_ as the
|
||||
// union itself, so flatvariantidx finds no variant and returns -1,
|
||||
// matching cstage's loud (caller emits "unsupported variant init",
|
||||
// cgen.ww:2818). The shape fallback instead picked the first scalar
|
||||
// variant (tag 0) -> SILENT miscompile (ran the int arm on a bool
|
||||
// value, the S1 coincidence trap). A bare-literal init (`= true` / `=
|
||||
// 7`) keeps its concrete/untyped type and still resolves via
|
||||
// flatvariantidx pass 1 (byte-id with cstage); a str-literal CAST
|
||||
// (`"hi": u`) keeps its str type and resolves to the str variant too.
|
||||
// Faithful tag-remap for a cast-init static global = the deferred
|
||||
// #23/#40 nominal widen feature.
|
||||
let tag: i32 = flatvariantidx(c, tt, r);
|
||||
if (tag < 0) { return false; };
|
||||
let wide: bool = nodeisstr(c, r) || nodeisslice(c, r);
|
||||
let i: i32 = 0;
|
||||
|
||||
@@ -41336,7 +41336,22 @@ fn emittaggeddata(c: *cgen, name: str, module: str, tt: *node, rhs: *node, sz: i
|
||||
let r: *node = rhs;
|
||||
for (r != nil && r.kind == nkind.N_CAST) { r = r.lhs; };
|
||||
if (r == nil) { return false; };
|
||||
let tag: i32 = taggedvariantindex(c, tt, r);
|
||||
// E8/#35: select the variant via flatvariantidx — the EXACT twin of
|
||||
// cstage emit_tagged_data's cg_tag_for_variant (cmd/w6c/cgen.c:15472).
|
||||
// taggedvariantindex adds a str/slice SHAPE fallback (cgenutil.ww:3054)
|
||||
// that cstage does NOT run at this site: a same-type/subset CAST init
|
||||
// (`let g: u = true: u;`) stamps the peeled literal's type_ as the
|
||||
// union itself, so flatvariantidx finds no variant and returns -1,
|
||||
// matching cstage's loud (caller emits "unsupported variant init",
|
||||
// cgen.ww:2818). The shape fallback instead picked the first scalar
|
||||
// variant (tag 0) -> SILENT miscompile (ran the int arm on a bool
|
||||
// value, the S1 coincidence trap). A bare-literal init (`= true` / `=
|
||||
// 7`) keeps its concrete/untyped type and still resolves via
|
||||
// flatvariantidx pass 1 (byte-id with cstage); a str-literal CAST
|
||||
// (`"hi": u`) keeps its str type and resolves to the str variant too.
|
||||
// Faithful tag-remap for a cast-init static global = the deferred
|
||||
// #23/#40 nominal widen feature.
|
||||
let tag: i32 = flatvariantidx(c, tt, r);
|
||||
if (tag < 0) { return false; };
|
||||
let wide: bool = nodeisstr(c, r) || nodeisslice(c, r);
|
||||
let i: i32 = 0;
|
||||
|
||||
Reference in New Issue
Block a user