cstage+selfhost+test: fold N_UN over signed int literal in let DATA emit (#19)
emit_lets / emitletdataw's scalar-8B and array arms only matched bare N_INTLIT / N_RUNELIT / N_TRUE / N_FALSE / N_NIL on the let rhs. `let x: i8 = -1i8;` arrives as N_UN(TK_MINUS, N_INTLIT(1)) — none of those — so cstage's scalar arm hit `else continue;` and dropped the DATAW row entirely; the array arm bailed at the first non-foldable element and the skip-array-with-non-NIL-rhs fall-through dropped the whole row. Wwstage's mirror arms silently emitted zero bytes for negative literals in both shapes. Severity split — cstage symptom is no DATA emit, the linker fails loudly at build time. Wwstage symptom is silent-zero element substitution for negative array values: compiles, runs, returns wrong answers. Corpus-coverage-blind on the wwstage side, only surfaces when a consumer reads the wrong value. Single N_UN-fold helper application retires both symptoms across both stages. Fourth corpus-coverage-blind unmask this session (catalog: i64 div/mod CQO #16, IDENT-local /= no-op, #21 call-arg DX drop, now #19 wwstage silent-zero). Route all four sites through fold_int_literal / foldintliteral, the same helper #24 used on the def-emit side (which already covered N_UN over the leaf set). The wwstage array arm also picks up an N_CAST peel and drops a dead non-`...` N_FIELD branch (the parser never emits non-`...` N_FIELD inside an N_ARRLIT — only as the `...` repeat marker). Same-path sibling cleanup; rule-11 justified. Tests: - 719_signed_data_emit asserts DATAW <sym>(SB),"<bytes>" lines are present in both stages' .s for the {i8, i16, i32, i64} × {scalar, 1D array} matrix, plus cmp -s byte-id between stages per row. Corpus-coverage-blind sentinel per rob's STATUS-3 note. - 923_signed_data_emit_run runtime-pins the same matrix plus a TK_TILDE row through cstage and wwstage drivers. 995_self_rebuild stays green (ww2==ww3==ww4 byte-id).
This commit is contained in:
@@ -7111,12 +7111,14 @@ emit_lets(Cg *c, FILE *out, Node *file)
|
||||
Node *r = d->rhs;
|
||||
while (r != NULL && r->kind == N_CAST) r = r->lhs;
|
||||
if (r == NULL) continue;
|
||||
if (r->kind == N_INTLIT) v = r->uval;
|
||||
else if (r->kind == N_RUNELIT) v = r->uval;
|
||||
else if (r->kind == N_TRUE) v = 1;
|
||||
else if (r->kind == N_FALSE) v = 0;
|
||||
else if (r->kind == N_NIL) v = 0;
|
||||
else continue;
|
||||
/* Same helper as emit_defs (#24): widens
|
||||
* the gate to cover N_UN(TK_MINUS/TILDE/PLUS,
|
||||
* leaf) so `let x: i8 = -1i8;` and friends
|
||||
* encode as sign-extended two's-complement
|
||||
* bytes. emit_data_row writes 8 LE bytes
|
||||
* so narrow signed types just naturally
|
||||
* round-trip via the sign-extended u64. */
|
||||
if (!fold_int_literal(r, &v)) continue;
|
||||
}
|
||||
emit_data_row(out, "DATAW", mod_mangle(c, d->str), v);
|
||||
continue;
|
||||
@@ -7170,15 +7172,12 @@ emit_lets(Cg *c, FILE *out, Node *file)
|
||||
Node *ev = e;
|
||||
while (ev && ev->kind == N_CAST) ev = ev->lhs;
|
||||
if (ev == NULL) { ok = 0; break; }
|
||||
if (ev->kind == N_INTLIT || ev->kind == N_RUNELIT) {
|
||||
last = ev->uval;
|
||||
} else if (ev->kind == N_TRUE) {
|
||||
last = 1;
|
||||
} else if (ev->kind == N_FALSE) {
|
||||
last = 0;
|
||||
} else if (ev->kind == N_NIL) {
|
||||
last = 0;
|
||||
} else {
|
||||
/* Same helper as the scalar arm above —
|
||||
* fold_int_literal covers N_UN over a leaf
|
||||
* so signed-negative array elements (`-1i8`)
|
||||
* encode as their two's-complement bytes
|
||||
* once truncated to esz below. */
|
||||
if (!fold_int_literal(ev, &last)) {
|
||||
ok = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user