boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

commit 9f93e8e0c21f5d6359a19015ea431fb420e6e750
parent fc1600e196f0e0c4ef8c3bbef397c119e80476d7
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Fri,  1 May 2026 17:45:38 -0700

cc/cg: promote narrow integers to (signed) int

C 6.3.1.1 says _Bool, char, short, and any narrower integer type
whose values all fit in int promote to int (signed). cg-promote
previously kept the source signedness — narrow unsigned types went
to u32 — which dragged the subsequent cg-arith-conv into picking
the unsigned common type and flipped the signedness of `>>`,
ordered comparisons, division, etc. away from the C rule. Always
promote to i32; any narrow value's canonical 64-bit slot form
already matches i32 so the cast stays relabel-only.

New cc-cg fixture 84-bool-promotes-int locks in (_Bool=1) * -1
== -1 — previously 0 because the bool→u32 promotion forced an
unsigned multiply.

Diffstat:
Mcc/cc.scm | 14+++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/cc/cc.scm b/cc/cc.scm @@ -3472,12 +3472,16 @@ (ty (opnd-type p)) (sz (ctype-size ty))) (cond + ;; C 6.3.1.1: _Bool, char, short, and any narrower int type + ;; promote to (signed) int — every representable value fits + ;; in i32. Treating narrow unsigned types as u32 here would + ;; drag the subsequent arith-conv into picking the unsigned + ;; common type, flipping signedness of `>>`, comparisons, + ;; division, etc. against the C rule. Canonical form for any + ;; in-range narrow value already matches i32, so the cast is + ;; relabel-only. ((< sz 4) - (cond - ((%ctype-unsigned? ty) - (cg-push cg (%opnd (opnd-kind p) %t-u32 (opnd-ext p) (opnd-lval? p)))) - (else - (cg-push cg (%opnd (opnd-kind p) %t-i32 (opnd-ext p) (opnd-lval? p)))))) + (cg-push cg (%opnd (opnd-kind p) %t-i32 (opnd-ext p) (opnd-lval? p)))) (else (cg-push cg p))))) (define (cg-arith-conv cg)