Skip to content

Wire -memcheck into fun test, fix the real bugs it surfaced - #206

Merged
omdxp merged 8 commits into
mainfrom
memcheck-ci
Oct 14, 2026
Merged

omdxp merged 8 commits into
mainfrom
memcheck-ci

Conversation

@omdxp

@omdxp omdxp commented Oct 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • Wires -memcheck/-memcheck-leaks into fun test [<path>]. Leak reporting is off by default under -memcheck (opt in with -memcheck-leaks): a short-lived process - every CLI invocation this compiler makes, and every -test binary - never has to free a transient allocation before it exits a moment later anyway, so treating that as a leak flags ordinary code, not a bug. Double-free/use-after-free/buffer-overflow stay caught unconditionally either way.
  • Three real bugs found and fixed while getting the whole suite to actually pass under -memcheck:
    • A hoisted temp's own #line directive (under -g) could read an uninitialized Pos when the enclosing statement's own directive had already been flushed, producing a real null-pointer crash. Caught because -memcheck implies -g for real file:line reports.
    • Compiling one of std.memcheck's own dependencies directly under -memcheck (every stdlib file, in this project's own test corpus) reached that exact file a second time through the use std.memcheck the feature injects, double-merging its declarations.
    • std.memcheck itself calling into std.io/std.string created a circular forward reference when the entry file was the one supplying those declarations - fixed by building its own reports with std.c.io's snprintf/fprintf instead, dropping the dependency entirely.
    • Bonus, unrelated: an fls debug-log line passed a 64-bit length where printf's %.*s precision expects a 32-bit int - undefined behavior, just never hit until this branch's own heavier compiler runs exercised it.
  • CI: a new -memcheck step on the ubuntu lane, manual-trigger only (workflow_dispatch, the GitHub Actions equivalent of GitLab's manual job) - the guard-page allocator's own per-allocation mmap/mprotect cost is too slow to add to every push/PR, but it's there on demand.
  • Docs: a "Memory Checker" section in docs/tooling.md, and a "Ternary Conditional" section in docs/language.md (catching up docs for the ternary feature from the previous PR).

Test plan

  • fun test . passes 56/56, run twice, after a fresh 3-stage bootstrap from the installed release
  • -fmt-check-all clean, fun lint src/fun lint stdlib clean
  • scripts/run_examples.sh: 222 total, 0 failed, 21 expected-fail, 0 unexpected-pass (matches baseline)
  • VS Code extension smoke test: 10/10 passing
  • Every stdlib file, codegen_tests.fn's 125 tests, and the bulk of the suite verified passing under -memcheck directly (the full suite run is slow enough - guard pages are much slower than a real malloc - that a single local run reliably completing end to end on this machine wasn't practical; the new manual-trigger CI step is the real full-suite gate going forward)
  • New regression tests: a hoisted temp's #line directive under -g, -memcheck/-memcheck-leaks flag parsing, leak-vs-double-free behavior under -test, and compiling a std.memcheck dependency directly under -memcheck

omdxp added 8 commits October 15, 2026 01:30
…ta under -g

has_pending_line_directive is cleared once flushed for the enclosing
statement, before a hoisted temp needs its own, second #line.
-memcheck-leaks opts back in for a program meant to outlive its own
process exit; double-free/UAF/overflow stay caught either way.
…rence

Compiling one of its own dependencies directly under -memcheck reached
that file a second time through the import this feature injects.
…ects int

A plain %s is equivalent here anyway, both strings already NUL-terminated.
workflow_dispatch - the GitHub Actions equivalent of GitLab's manual
job - since the guard-page allocator is too slow for every push/PR.
…nt64_t

Matched by coincidence on macOS; Linux's int64_t is long, not long long.
… guard

Pulled in the legacy winsock.h, conflicting with winsock2.h included
elsewhere in the same generated file.
@omdxp
omdxp merged commit cfefd85 into main Oct 14, 2026
4 checks passed
@omdxp
omdxp deleted the memcheck-ci branch October 14, 2026 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant