flan/test/programs/reach-walk.flan
Joseph Ferano 86d0c14a45 Three edges of Reach's walk that nothing called
An index expression inside a place, a place under addr, and a
restart-case clause body are each the only route to a function in
reach-walk.flan. Drop any one of the three from the walk and the
function is not emitted, so the program stops linking rather than
answering wrong; each mutation was planted and watched fail here. The
addr case goes through a deref place on purpose, so the index case
cannot stand in for it.
2026-09-12 10:38:40 +07:00

54 lines
1.9 KiB
Plaintext

;;;; Three edges of Reach's walk, each the only route to one function.
;;;;
;;;; A release build is pruned: a function nothing reachable from main or from
;;;; a global initialiser calls is not emitted at all. So an edge the walk
;;;; forgets does not produce a wrong answer — it produces a program that does
;;;; not link, with a message about a symbol nobody wrote. Each of the three
;;;; functions below is called from exactly one place, and that place is an
;;;; edge no other program in the corpus exercises:
;;;;
;;;; index-of the index expression of a place, (set (at a (f)) v)
;;;; through a place under (addr ...), here a (deref ...) so that it is
;;;; the addr edge and not the index one again
;;;; placeholder a restart-case clause body, which is reached by a transfer
;;;; and never by a call the walk can see from the body
;;;;
;;;; Nothing here is about the values; the values are how the test notices that
;;;; the program was built and ran at all.
(defvar cells [4 i32])
(defvar slot i32)
(defstruct Nope [id i32])
(defn index-of [] i32 2)
(defn through [] (Ptr i32) (addr slot))
(defn placeholder [] i32 42)
;;; Signals with nothing to return, so the clause body is the only way past.
(defn missing [] i32
(error (Nope {:id 1})))
(defn pick [] i32
(restart-case (missing)
(use-placeholder [] (placeholder))))
(defn main [] i32
;; The index of a place is an expression, and it can call.
(set (at cells (index-of)) 10)
(print (at cells 2)) (println "")
;; (addr (deref p)) is p, so this is the addr edge over a place whose own
;; walk is Pderef rather than Pindex — the index case above cannot stand in
;; for it.
(let [q (addr (deref (through)))]
(set (deref q) 20))
(print slot) (println "")
;; The clause body, reached only because the handler transfers into it.
(handler-bind [(Nope [c] (invoke-restart 'use-placeholder))]
(print (pick)) (println ""))
0)