kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit 2bdeb46f9c551570bc731997aad31fc6991e5449
parent 6e16d41536712479f63a338cbacd62feca3dfddf
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Tue, 26 May 2026 17:51:19 -0700

parse: fix _Bool conversion to emit compare-against-zero rather than truncate

Converting a non-bool scalar to _Bool is semantically "value != 0", not a
width truncation. A value whose set bits all lie above the bool storage width
(e.g. 256, or the sign bit of a 128-bit operand) must still produce 1. Emit
an explicit compare-against-zero (int or fp) followed by a narrow trunc for
any non-bool scalar source.

Diffstat:
Mlang/c/parse/cg_adapter.c | 20++++++++++++++++++++
1 file changed, 20 insertions(+), 0 deletions(-)

diff --git a/lang/c/parse/cg_adapter.c b/lang/c/parse/cg_adapter.c @@ -785,6 +785,26 @@ void pcg_convert(Parser* p, const Type* dst) { CfreeCgTypeId id = pcg_tid(p, dst); int emit = pcg_emit_enabled(p); if (src == dst) return; + /* Conversion to _Bool is "value != 0", not a truncation: a value whose set + * bits all lie above the bool storage width (e.g. 256, or the sign bit of a + * 128-bit operand) must still become 1. Emit an explicit compare-against-zero + * for any non-bool scalar source. */ + if (dst->kind == TY_BOOL && src->kind != TY_BOOL) { + if (emit) { + CfreeCgTypeId sid = pcg_tid(p, src); + if (sf) { + cfree_cg_push_float(p->cg, 0.0, sid); + cfree_cg_fp_cmp(p->cg, CFREE_CG_FP_UNE); + } else { + cfree_cg_push_int(p->cg, 0, sid); + cfree_cg_int_cmp(p->cg, CFREE_CG_INT_NE); + } + /* The compare yields a 0/1 int; narrow it to the bool storage width. */ + cfree_cg_trunc(p->cg, id); + } + pcg_retag_top(p, dst); + return; + } if (type_is_ptr(src) && type_is_ptr(dst)) { if (emit) cfree_cg_bitcast(p->cg, id); pcg_retag_top(p, dst);