check: type the N_BIN operand of as in the wwstage
An enum OR-fold under `as` ((m.A|m.B) as u32) was never typed: scruttype resolves IDENT/DOT only, and the post-order restamp then re-derived the folded member literals as untyped_int. The unstamped operand missed cgtypeassert's #27b enum-reinterpret gate and lowered as a phantom tagged assert — unconditional exit 1 at runtime on the wwstage leg. checkisas now types an N_BIN lhs and the N_BIN restamp preserves an existing enum stamp. Graduates the #59.9 stattest pin.
This commit is contained in:
@@ -3328,6 +3328,22 @@ fn exprtype(c: *checker, e: *syntax.node, hint: *syntax.node) *syntax.node = {
|
||||
};
|
||||
if (k == syntax.nkind.N_BIN) {
|
||||
let tn: *syntax.node = binoptype(c, e);
|
||||
// #59.9: checkisas pre-stamps an enum OR-fold (`(m.A|m.B) as
|
||||
// u32`) TY_ENUM and folds the member N_DOTs to int literals;
|
||||
// this post-order revisit re-derives from those now-untyped
|
||||
// literals and clobbered the stamp, so cgtypeassert's #27b
|
||||
// reinterpret gate missed and emitted a phantom tagged assert
|
||||
// (unconditional exit 1). Keep an existing enum stamp; the
|
||||
// returned tnode contract for callers is unchanged.
|
||||
let pre599: *syntax.tinfo = e.type_: *syntax.tinfo;
|
||||
if (pre599 != nil) {
|
||||
let prech: *syntax.tinfo = tichase(pre599);
|
||||
if (prech != nil) {
|
||||
if (prech.kind == syntax.tykind.TY_ENUM) {
|
||||
return tn;
|
||||
};
|
||||
};
|
||||
};
|
||||
e.type_ = tinfofornode(c, tn): *void;
|
||||
return tn;
|
||||
};
|
||||
@@ -6353,6 +6369,15 @@ fn checkisas(c: *checker, n: *syntax.node) void = {
|
||||
if (n.lhs.kind == syntax.nkind.N_TRYPROP || n.lhs.kind == syntax.nkind.N_TRYUNW) {
|
||||
st = exprtype(c, n.lhs, nil);
|
||||
};
|
||||
// #59.9: an N_BIN operand (`(m.A | m.B) as u32`) was never
|
||||
// typed, so the OR-fold reached cgen unstamped and
|
||||
// cgtypeassert's enum-reinterpret gate (#27b) missed —
|
||||
// lowering a plain enum value as a phantom tagged assert
|
||||
// (unconditional exit 1). cstage types the lhs
|
||||
// unconditionally (cmd/wcc/check.c:2220 cexpr(c, n->lhs)).
|
||||
if (n.lhs.kind == syntax.nkind.N_BIN) {
|
||||
st = exprtype(c, n.lhs, nil);
|
||||
};
|
||||
};
|
||||
let u: *syntax.node = resolvealias(c, unwrapbang(st));
|
||||
if (u == nil) { return; };
|
||||
|
||||
Reference in New Issue
Block a user