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:
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)))