boot2

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

commit 4159f6046e8f38de576b2c260d63757a0c9a2a8b
parent 6d7c97261fba09e32ae624b3c582bceb5f3cd14d
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Sun, 26 Apr 2026 22:46:19 -0700

cc tests: function-pointer call (§K.2)

Verifies cg-call's indirect path (%callr(t0)) when the fn opnd is a
non-fn-typed (frame) lval that loads a fn-pointer address. Also
exercises return-type extraction through ptr -> fn -> ret.

cg fixture drives the API directly. parse fixture verifies the same
end-to-end via `int (*fp)(int)` declaration syntax.

Diffstat:
Atests/cc-cg/67-fnptr-call.expected-exit | 1+
Atests/cc-cg/67-fnptr-call.scm | 40++++++++++++++++++++++++++++++++++++++++
Atests/cc-parse/71-fnptr-call.c | 8++++++++
Atests/cc-parse/71-fnptr-call.expected-exit | 1+
4 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/tests/cc-cg/67-fnptr-call.expected-exit b/tests/cc-cg/67-fnptr-call.expected-exit @@ -0,0 +1 @@ +21 diff --git a/tests/cc-cg/67-fnptr-call.scm b/tests/cc-cg/67-fnptr-call.scm @@ -0,0 +1,40 @@ +;; tests/cc-cg/67-fnptr-call.scm — function-pointer call (§K.2). +;; Models: +;; int triple(int x) { return x + x + x; } +;; int main(void) { +;; int (*fp)(int) = triple; +;; return fp(7); /* 21 */ +;; } +;; Exercises cg-call's %callr(t0) branch when the fn opnd is a +;; non-fn-typed (frame) operand: the address is loaded into t0. + +(let* ((cg (cg-init)) + (triple-fnty (%ctype 'fn 8 8 (cons %t-i32 (cons (list %t-i32) #f)))) + (triple-sym (%sym "triple" 'fn 'extern triple-fnty #f))) + ;; int triple(int x) { return x + x + x; } + (let* ((params (cg-fn-begin cg "triple" + (list (cons "x" %t-i32)) + %t-i32)) + (x* (cdr (car params)))) + (cg-push-sym cg x*) (cg-load cg) + (cg-push-sym cg x*) (cg-load cg) (cg-binop cg 'add) + (cg-push-sym cg x*) (cg-load cg) (cg-binop cg 'add) + (cg-return cg) + (cg-fn-end cg)) + ;; int main(void) { int (*fp)(int) = triple; return fp(7); } + (let* ((params (cg-fn-begin cg "main" '() %t-i32)) + (fp-ty (%ctype 'ptr 8 8 triple-fnty)) + (fp-sl (cg-alloc-slot cg 8 8)) + (fp-sym (%sym "fp" 'var 'auto fp-ty fp-sl))) + ;; fp = triple (address of fn into the slot) + (cg-push-sym cg fp-sym) + (cg-push-sym cg triple-sym) + (cg-cast cg fp-ty) + (cg-assign cg) (cg-pop cg) + ;; fp(7) — cg-call expects fn opnd at vstack-bottom of the args. + (cg-push-sym cg fp-sym) (cg-load cg) + (cg-push-imm cg %t-i32 7) + (cg-call cg 1 #t) + (cg-return cg) + (cg-fn-end cg)) + (write-bv-fd 1 (cg-finish cg))) diff --git a/tests/cc-parse/71-fnptr-call.c b/tests/cc-parse/71-fnptr-call.c @@ -0,0 +1,8 @@ +/* §K.2 — function-pointer call. */ +int triple(int x) { return x + x + x; } + +int main(void) { + int (*fp)(int); + fp = triple; + return fp(7); /* 21 */ +} diff --git a/tests/cc-parse/71-fnptr-call.expected-exit b/tests/cc-parse/71-fnptr-call.expected-exit @@ -0,0 +1 @@ +21