wcc/ww: typeeqast identity fast-path for shared type nodes (#36)
wwstage's typeeqast lacked the identity short-circuit cstage type_eq opens with (cmd/wcc/type.c:250 `if (a == b) return 1`). Enum/struct/ array type nodes are shared from their decl, so two references to the same type resolve to one node; without the fast-path the catch-all returns false. Exposed by #26's integer-mismatch reject, which fired on a same-enum binop like w6l's `os.flag.WRONLY|CREATE|TRUNC` that cstage accepts via this check. Corpus output unchanged (the w6c_ww/ wwdump_ww binaries move because check.ww regenerates combined.ww).
This commit is contained in:
@@ -11424,6 +11424,14 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = {
|
||||
let bb: *node = unwrapbang(b);
|
||||
if (aa == nil) { return bb == nil; };
|
||||
if (bb == nil) { return false; };
|
||||
// Identity fast-path, mirroring cstage type_eq's first line
|
||||
// (cmd/wcc/type.c:250 `if (a == b) return 1`). Enum (and struct/
|
||||
// array) type nodes are shared from their decl, so two references to
|
||||
// the SAME `os.flag` resolve to one N_TENUM node; without this the
|
||||
// catch-all below returns false and the #26 reject fires on a
|
||||
// same-enum binop like `os.flag.WRONLY | os.flag.CREATE` (w6l), which
|
||||
// cstage accepts via this identity check.
|
||||
if (aa == bb) { return true; };
|
||||
if (aa.kind != bb.kind) { return false; };
|
||||
let k: nkind = aa.kind;
|
||||
if (k == nkind.N_TNAME) {
|
||||
|
||||
@@ -954,6 +954,14 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = {
|
||||
let bb: *node = unwrapbang(b);
|
||||
if (aa == nil) { return bb == nil; };
|
||||
if (bb == nil) { return false; };
|
||||
// Identity fast-path, mirroring cstage type_eq's first line
|
||||
// (cmd/wcc/type.c:250 `if (a == b) return 1`). Enum (and struct/
|
||||
// array) type nodes are shared from their decl, so two references to
|
||||
// the SAME `os.flag` resolve to one N_TENUM node; without this the
|
||||
// catch-all below returns false and the #26 reject fires on a
|
||||
// same-enum binop like `os.flag.WRONLY | os.flag.CREATE` (w6l), which
|
||||
// cstage accepts via this identity check.
|
||||
if (aa == bb) { return true; };
|
||||
if (aa.kind != bb.kind) { return false; };
|
||||
let k: nkind = aa.kind;
|
||||
if (k == nkind.N_TNAME) {
|
||||
|
||||
@@ -11424,6 +11424,14 @@ fn typeeqast(c: *checker, a: *node, b: *node) bool = {
|
||||
let bb: *node = unwrapbang(b);
|
||||
if (aa == nil) { return bb == nil; };
|
||||
if (bb == nil) { return false; };
|
||||
// Identity fast-path, mirroring cstage type_eq's first line
|
||||
// (cmd/wcc/type.c:250 `if (a == b) return 1`). Enum (and struct/
|
||||
// array) type nodes are shared from their decl, so two references to
|
||||
// the SAME `os.flag` resolve to one N_TENUM node; without this the
|
||||
// catch-all below returns false and the #26 reject fires on a
|
||||
// same-enum binop like `os.flag.WRONLY | os.flag.CREATE` (w6l), which
|
||||
// cstage accepts via this identity check.
|
||||
if (aa == bb) { return true; };
|
||||
if (aa.kind != bb.kind) { return false; };
|
||||
let k: nkind = aa.kind;
|
||||
if (k == nkind.N_TNAME) {
|
||||
|
||||
Reference in New Issue
Block a user