codegen: Bool is int-like, so Bool comparisons stop lowering to str_eq #138
Reference in New Issue
Block a user
Delete Branch "fix/bool-is-int-like"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Bool has always been an integer in the value model —
type_to_cmapsBool → "int", andel_runtime.hsays "Bool -> el_val_t (0 = false, nonzero = true)". But Bool names were registered nowhere: params tracked Int and Float,lettracked Int and Float. Neither knew about Bool.So comparing two Bools fell through to
str_eq, dereferencing 0 or 1 as achar*.Third instance of one family tonight, after #137 (a call on either side of
==poisoned the operator) and #136 (a missing import compiled clean). Same shape each time: something the compiler couldn't type, silently handled as a string.Found while writing #137's own test harness — the first version crashed on exactly this, on both old and new compilers. A test harness that can't compare two Bools is a good way to notice.
Verified:
Adds
tests/runtime/operator_typing_test.elso this family is covered going forward rather than rediscovered.fn check(label: String, cond: Bool, want: Bool) -> Void { if cond == want { ... } -> if (str_eq(cond, want)) SIGSEGV } Bool has always been an integer in the value model — type_to_c maps Bool to "int", and el_runtime.h states "Bool -> el_val_t (0 = false, nonzero = true)". But Bool names were registered NOWHERE: build_int_names_for_params tracked Int and Float params, and the `let` path tracked Int and Float bindings. Neither knew about Bool. So comparing two Bools fell through to str_eq, which dereferenced 0 or 1 as a char* and segfaulted immediately. This is the third instance of one family found tonight, after el #137 (a call on either side of == poisoned the operator) and el #136 (a missing import compiled clean). All three are the same shape: something the compiler could not type, silently handled as a string. Found while writing #137's own test harness — the first version of that harness crashed on exactly this, on both the old and new compiler, which is how it surfaced. A test harness that cannot compare two Bools is a good way to notice. VERIFIED: - the harness that segfaulted on every prior compiler (exit 139, no output) now runs clean: 14 passed, 0 failed - self-hosting fixpoint byte-identical - the compiler's own generated C differs by 8 lines — only the intended registration - neuron's full soul amalgam regenerates in 424ms, exit 0, BYTE-IDENTICAL - test_math 13/13, test_string 27/27, test_core 10/10, test_text 12/12 Adds tests/runtime/operator_typing_test.el, the 15-case suite from #137, so this family is covered going forward rather than rediscovered.