boot2

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

commit 75c2bc723023f8c895930d2c4855045d9eb8ed41
parent 8755ab3a67b482d417439ec467f2c6babda7dcab
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Sun, 26 Apr 2026 22:39:39 -0700

cc tests: variadic call site exercises cg-promote per arg (§G.1)

Drives cg-call directly with cg-promote on each variadic arg before
push. Locks in the cg-side contract for §G.1 — parser-side per-arg
default-promote lands next.

Diffstat:
Atests/cc-cg/66-vararg-call.expected-exit | 1+
Atests/cc-cg/66-vararg-call.scm | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/tests/cc-cg/66-vararg-call.expected-exit b/tests/cc-cg/66-vararg-call.expected-exit @@ -0,0 +1 @@ +16 diff --git a/tests/cc-cg/66-vararg-call.scm b/tests/cc-cg/66-vararg-call.scm @@ -0,0 +1,57 @@ +;; tests/cc-cg/66-vararg-call.scm — variadic call with default-promoted args (§G.1). +;; Models a variadic callee that just sums two int args after the named one. +;; int sum_var(int n, ...) { +;; int *ap = ((int*)(&n)) + 1; /* hand-rolled vararg access */ +;; return n + ap[0] + ap[1]; +;; } +;; int main(void) { +;; signed char c = 5; +;; short s = 10; +;; /* C semantics: c and s are promoted to int at the call site. */ +;; return sum_var(1, c, s); /* 1 + 5 + 10 = 16 */ +;; } +;; +;; What the cc-cg fixture exercises is the *caller* side: cg-promote on +;; each variadic arg before cg-call. The callee uses fixed-arg ABI here +;; for simplicity; va_arg/va_start/va_end are §G.2. + +(let* ((cg (cg-init)) + (sumv-fnty (%ctype 'fn 8 8 (cons %t-i32 (cons (list %t-i32) #t)))) + (sumv-sym (%sym "sum_var" 'fn 'extern sumv-fnty #f))) + ;; int sum_var(int n, int a, int b) { return n + a + b; } + ;; (Modeling 3 fixed params; the callee doesn't care about variadic + ;; ABI in this fixture — see §G.2 for that.) + (let* ((params (cg-fn-begin cg "sum_var" + (list (cons "n" %t-i32) + (cons "a" %t-i32) + (cons "b" %t-i32)) + %t-i32)) + (n* (cdr (car params))) + (a* (cdr (car (cdr params)))) + (b* (cdr (car (cdr (cdr params)))))) + (cg-push-sym cg n*) (cg-load cg) + (cg-push-sym cg a*) (cg-load cg) (cg-binop cg 'add) + (cg-push-sym cg b*) (cg-load cg) (cg-binop cg 'add) + (cg-return cg) + (cg-fn-end cg)) + ;; int main(void) { signed char c=5; short s=10; return sum_var(1, c, s); } + (let* ((params (cg-fn-begin cg "main" '() %t-i32)) + (c-sl (cg-alloc-slot cg 1 1)) + (s-sl (cg-alloc-slot cg 2 2)) + (c-sym (%sym "c" 'var 'auto %t-i8 c-sl)) + (s-sym (%sym "s" 'var 'auto %t-i16 s-sl))) + ;; c = 5; + (cg-push-sym cg c-sym) (cg-push-imm cg %t-i32 5) + (cg-assign cg) (cg-pop cg) + ;; s = 10; + (cg-push-sym cg s-sym) (cg-push-imm cg %t-i32 10) + (cg-assign cg) (cg-pop cg) + ;; sum_var(1, c, s) — promote c and s to int at the call site + (cg-push-sym cg sumv-sym) + (cg-push-imm cg %t-i32 1) ; named-arg n + (cg-push-sym cg c-sym) (cg-load cg) (cg-promote cg) ; variadic c + (cg-push-sym cg s-sym) (cg-load cg) (cg-promote cg) ; variadic s + (cg-call cg 3 #t) + (cg-return cg) + (cg-fn-end cg)) + (write-bv-fd 1 (cg-finish cg)))