diff --git a/test/programs/reload.flan b/test/programs/reload.flan index 6e7579f..6d2b19e 100644 --- a/test/programs/reload.flan +++ b/test/programs/reload.flan @@ -27,6 +27,14 @@ ;;; question. (defonce spare i64) +;;; Unused too, and here for the redefinition-module question a [def] adds: +;;; its initialiser is lifted into [global/paint] whatever it is — a literal +;;; included — so re-evaluating the form republishes that function through +;;; its cell, and [global/paint] is a *non-sibling* target (its parent is the +;;; global, not a function in the form). test_reload greps the module's IR +;;; for the cell declaration that publish needs. +(def paint i64 7) + ;;; Also unused, and for the same reason: a defconst's value and an enum ;;; member are folded into every call site, so a session has to refuse changing ;;; either. Nothing here reads them, so the checker has no opinion and the diff --git a/test/test_reload.ml b/test/test_reload.ml index b2053bc..67366a5 100644 --- a/test/test_reload.ml +++ b/test/test_reload.ml @@ -125,6 +125,21 @@ let () = fail "redefinition's own body is interposable"; if not (has ir2 "@\"flan.cell.helper\" = external global ptr") then fail "redefinition defines a cell instead of using the host's"; + (* A def's lifted initialiser as the target, which is what [Session]'s + [def_inits] hands in when the form is re-evaluated. [global/paint] is + not a sibling — its [fparent] is the global it initialises, not a + function in [fns] — so its cell declaration comes from the targets + pass in [Emit.redefinition]; without that pass the publish store + names a symbol the module never declared and the IR does not compile. + The x86 side needs no twin: it reaches a host cell through the GOT by + name, declared or not. *) + (let irdef = + Emit.redefinition ~dev:true ~known p1 ~fns:[ "global/paint" ] + in + if not (has irdef "@\"flan.cell.global/paint\" = external global ptr") + then fail "a lifted def initialiser's cell is not declared"; + if not (has irdef "define hidden i64 @\"flan.global/paint\"") then + fail "a lifted def initialiser's body is missing or interposable"); (* A name the host has is a symbol; a name it lacks is a registry lookup cached in a module-local slot. Getting this backwards either fails to link or silently gives each module its own copy. *)