066-vararg-call.scm (2538B)
1 ;; tests/cc-cg/66-vararg-call.scm — variadic call with default-promoted args (§G.1). 2 ;; Models a variadic callee that just sums two int args after the named one. 3 ;; int sum_var(int n, ...) { 4 ;; int *ap = ((int*)(&n)) + 1; /* hand-rolled vararg access */ 5 ;; return n + ap[0] + ap[1]; 6 ;; } 7 ;; int main(void) { 8 ;; signed char c = 5; 9 ;; short s = 10; 10 ;; /* C semantics: c and s are promoted to int at the call site. */ 11 ;; return sum_var(1, c, s); /* 1 + 5 + 10 = 16 */ 12 ;; } 13 ;; 14 ;; What the cc-cg fixture exercises is the *caller* side: cg-promote on 15 ;; each variadic arg before cg-call. The callee uses fixed-arg ABI here 16 ;; for simplicity; va_arg/va_start/va_end are §G.2. 17 18 (let* ((cg (cg-init)) 19 (sumv-fnty (%ctype 'fn 8 8 (cons %t-i32 (cons (list %t-i32) #t)))) 20 (sumv-sym (%sym "sum_var" 'fn 'extern sumv-fnty #f))) 21 ;; int sum_var(int n, int a, int b) { return n + a + b; } 22 ;; (Modeling 3 fixed params; the callee doesn't care about variadic 23 ;; ABI in this fixture — see §G.2 for that.) 24 (let* ((params (cg-fn-begin cg "sum_var" 25 (list (cons "n" %t-i32) 26 (cons "a" %t-i32) 27 (cons "b" %t-i32)) 28 %t-i32)) 29 (n* (cdr (car params))) 30 (a* (cdr (car (cdr params)))) 31 (b* (cdr (car (cdr (cdr params)))))) 32 (cg-push-sym cg n*) (cg-load cg) 33 (cg-push-sym cg a*) (cg-load cg) (cg-binop cg 'add) 34 (cg-push-sym cg b*) (cg-load cg) (cg-binop cg 'add) 35 (cg-return cg) 36 (cg-fn-end cg)) 37 ;; int main(void) { signed char c=5; short s=10; return sum_var(1, c, s); } 38 (let* ((params (cg-fn-begin cg "main" '() %t-i32)) 39 (c-sl (cg-alloc-slot cg 1 1)) 40 (s-sl (cg-alloc-slot cg 2 2)) 41 (c-sym (%sym "c" 'var 'auto %t-i8 c-sl)) 42 (s-sym (%sym "s" 'var 'auto %t-i16 s-sl))) 43 ;; c = 5; 44 (cg-push-sym cg c-sym) (cg-push-imm cg %t-i32 5) 45 (cg-assign cg) (cg-pop cg) 46 ;; s = 10; 47 (cg-push-sym cg s-sym) (cg-push-imm cg %t-i32 10) 48 (cg-assign cg) (cg-pop cg) 49 ;; sum_var(1, c, s) — promote c and s to int at the call site 50 (cg-push-sym cg sumv-sym) 51 (cg-push-imm cg %t-i32 1) ; named-arg n 52 (cg-push-sym cg c-sym) (cg-load cg) (cg-promote cg) ; variadic c 53 (cg-push-sym cg s-sym) (cg-load cg) (cg-promote cg) ; variadic s 54 (cg-call cg 3 #t) 55 (cg-return cg) 56 (cg-fn-end cg)) 57 (write-bv-fd 1 (cg-finish cg)))