selfhost: alias-aware istaggedtype for nested-union match
`type error = !(invalid | overflow)` miscompiled — istaggedtype only matched N_TTAGGED directly, so an `e: error` param spilled as 8B scalar and the match's slot+8 read trailed into saved BP. Mirror isstrtype's alias+bang unwrap; add resolvetagged() for is/as/match sites that need the inner N_TTAGGED. Frame scan counts via slotsize so wwstage stays byte-identical to cstage. Unblocks lib/strconv.strerror.
This commit is contained in:
@@ -470,6 +470,24 @@ static const struct row rows[] = {
|
||||
" };\n"
|
||||
" return 0;\n"
|
||||
"};", 40 },
|
||||
/* named alias over `!(A | B)`: param spill must size to the
|
||||
* flattened union (8B tag + 8B payload), not 8B-scalar. Pinned
|
||||
* the cstage/wwstage divergence where wwstage's istaggedtype
|
||||
* was alias-blind and the slot+8 read trailed into saved BP. */
|
||||
{ "type invalid = !i32;\n"
|
||||
"type overflow = !void;\n"
|
||||
"type error = !(invalid | overflow);\n"
|
||||
"fn errcode(e: error) i32 = {\n"
|
||||
" match (e) {\n"
|
||||
" case let v: invalid => return v: i32;\n"
|
||||
" case let v: overflow => return 99;\n"
|
||||
" };\n"
|
||||
" return 0;\n"
|
||||
"};\n"
|
||||
"fn main() i32 = {\n"
|
||||
" let e: error = 7: invalid;\n"
|
||||
" return errcode(e);\n"
|
||||
"};", 7 },
|
||||
/* str-typed variant payload: let-init with a string literal,
|
||||
* match-binding loads ptr+len from the slot */
|
||||
{ "fn main() i32 = {\n"
|
||||
|
||||
Reference in New Issue
Block a user