boot2

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

commit 16e81e5d753312600d9beaac52a9155841662cf0
parent 20bdc9d3b540ec050be7201600f9a67a18174cc8
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Wed,  6 May 2026 13:35:05 -0700

cc: widen integer literals exceeding INT_MAX to i64

parse-primary typed every INT token as i32, regardless of value. The
lexer drops u/U/l/L suffixes, so 4294967296L + 7L pushed both operands
as i32; cg-arith-conv kept the result i32 and cg-cast emitted a
trailing %sext32 after the 64-bit %add, truncating 0x100000007 to 7.

Pick %t-i64 when the value exceeds INT_MAX (C99 §6.4.4.1: smallest
type that holds the value). Fixes cc-libc/018-printf-int-promo on all
three arches.

Diffstat:
Mcc/cc.scm | 10+++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/cc/cc.scm b/cc/cc.scm @@ -7184,7 +7184,15 @@ (pmatch t (($ tok? (kind INT) (value ,n)) (advance ps) - (cg-push-imm (ps-cg ps) %t-i32 n)) + ;; C99 §6.4.4.1: pick the smallest type that holds the value. + ;; The lexer drops u/U/l/L suffixes before we get here, so we can't + ;; tell `0x1L` from `0x1`. But a value that doesn't fit in int has + ;; to widen anyway — otherwise `4294967296L + 7L` truncates to 7, + ;; because cg-arith-conv leaves both operands at i32 width. + (cg-push-imm (ps-cg ps) + (cond ((<= n 2147483647) %t-i32) + (else %t-i64)) + n)) (($ tok? (kind CHAR) (value ,c)) (advance ps) ;; C99 §6.4.4.4: an integer character constant has type int.