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:
@@ -169,8 +169,13 @@ static const struct ent ents[] = {
|
||||
/* #59.7 siphash graduated to M_ID above (#61 fix) */
|
||||
{ .fixture = "lib/log/logtest.ww",
|
||||
.mode = M_DIVERGE, .cite = "#59.8" },
|
||||
/* #59.9 graduated: the wwstage checker never typed an N_BIN operand
|
||||
* of `as`, so an enum OR-fold reached cgen unstamped and lowered as
|
||||
* a phantom tagged assert (unconditional exit 1). checkisas now
|
||||
* types the N_BIN lhs and the post-order restamp preserves the enum
|
||||
* stamp. Runtime pin: r599_enum_orfold_as. */
|
||||
{ .fixture = "lib/os/stattest.ww",
|
||||
.mode = M_DIVERGE, .cite = "#59.9" },
|
||||
.mode = M_ID, .cite = "#59.9 graduated by the checkisas N_BIN stamp" },
|
||||
/* #59.10 stoftest graduated to M_ID above (#62 fix) */
|
||||
{ .fixture = "lib/ww/syntax/toktest.ww", .inc = "lib/ww",
|
||||
.mode = M_ID, .cite = "#59.11 graduated by #146 str==" },
|
||||
|
||||
16
test/wcc/data/r599_enum_orfold_as/case.ww
Normal file
16
test/wcc/data/r599_enum_orfold_as/case.ww
Normal file
@@ -0,0 +1,16 @@
|
||||
//ww:run
|
||||
// #59.9: an enum member OR-fold under `as`. The pre-fix wwstage
|
||||
// checker never typed the N_BIN operand, so cgtypeassert's enum
|
||||
// reinterpret gate missed and lowered a phantom tagged assert that
|
||||
// unconditionally exited 1.
|
||||
package main;
|
||||
|
||||
type mask = enum u32 { A = 1, B = 2, C = 4 };
|
||||
|
||||
fn main() i32 = {
|
||||
let w: u32 = (mask.A | mask.B | mask.C) as u32;
|
||||
if (w != 7u32) { return 1; };
|
||||
let v: u32 = (mask.A | mask.C) as u32;
|
||||
if (v != 5u32) { return 2; };
|
||||
return 0;
|
||||
};
|
||||
Reference in New Issue
Block a user