diff --git a/test/dune b/test/dune index 143edfb..f004d77 100644 --- a/test/dune +++ b/test/dune @@ -145,10 +145,16 @@ (glob_files programs/*.flan) (glob_files programs/assets/*) (glob_files programs/assets/edn/*) + ; p13-dyn-collect.flan, which lives with the x86 probes because that is the + ; lane that wrote it, and is in this sweep because of what it does rather + ; than where it is: it is the only program anywhere that allocates past + ; flan_dyn.c's one-megabyte floor, so it is the only one under which a mark + ; and a sweep actually run. Every other Flan program here agrees with ASan + ; by never collecting at all. + (glob_files %{workspace_root}/spike/x86/*.flan) ; The dyn runtime's C main, which is the one thing in this sweep that is not - ; a Flan program: flan_dyn.c has no Flan spelling yet. It is also the one - ; translation unit here that frees anything, which is what makes it worth a - ; sanitized run at all. See [dyn_sweep]. + ; a Flan program. It is also the translation unit here that frees the most, + ; which is what makes it worth a sanitized run at all. See [dyn_sweep]. (file dyn_ops.c)) (action (run ./test_sanitize.exe))) diff --git a/test/test_sanitize.ml b/test/test_sanitize.ml index 72811c4..aa8ff79 100644 --- a/test/test_sanitize.ml +++ b/test/test_sanitize.ml @@ -158,6 +158,23 @@ let corpus = "programs/printers.flan", []; "programs/println.flan", []; "programs/restarts.flan", []; + (* The dyn programs, which reach flan_dyn.c from Flan rather than from the + hand-written C below — and the difference is the whole reason they are + here. [dyn_sweep] checks the collector against roots dyn_ops.c pushes + by hand; these check it against the roots the *compiler* emits, which + is the half no C test can reach. A root the emitter forgot is a live + object swept, and that is a use-after-free with the collector's own + hands on it. + [dyn-vec] is the one that builds objects of three kinds; [dyn-defer] + is the one whose roots come off on a transfer's path out rather than a + return's, which is where a pop written on one path only would show. + [p13] is the only program anywhere that allocates past flan_dyn.c's + one-megabyte floor, so it is the only one where a mark and a sweep + actually run — everything else in this list agrees with ASan by never + collecting at all. *) + "programs/dyn-vec.flan", []; + "programs/dyn-defer.flan", []; + "../spike/x86/p13-dyn-collect.flan", []; "programs/sand-headless.flan", []; "programs/signedness.flan", []; "programs/slices.flan", []; @@ -194,10 +211,15 @@ let sweep ~checks label = (try Sys.remove san with Sys_error _ -> ()))) corpus -(* The dyn runtime, under the same two sanitizers. It is not in [corpus] and - cannot be: there is no Flan program that reaches flan_dyn.c yet, so the - thing to build is test/dyn_ops.c against programs/dyn-host.flan — the same - pair test_dyn.ml builds, with [sanitize] on. +(* The dyn runtime, under the same two sanitizers, driven from C. There are + Flan programs that reach flan_dyn.c now and three of them are in [corpus] + above — this used to say there were none — but they are a different + question and not a replacement for this one. They exercise the roots the + *compiler* emits, over the handful of operations a program happens to + write; this exercises every entry point in the header, with the roots + pushed by hand so that the runtime can be wrong on its own. The thing to + build is test/dyn_ops.c against programs/dyn-host.flan — the same pair + test_dyn.ml builds, with [sanitize] on. This is the case the sweep is most likely to have something to say about. Every other program in the corpus allocates and never frees, which is a