Skip to content

build: carry -Werror=switch on the six remaining Makefile compile lines - #817

Merged
InauguralPhysicist merged 1 commit into
InauguralSystems:mainfrom
Nitjsefnie-OSC:build/werror-switch-alignment
Aug 2, 2026
Merged

build: carry -Werror=switch on the six remaining Makefile compile lines#817
InauguralPhysicist merged 1 commit into
InauguralSystems:mainfrom
Nitjsefnie-OSC:build/werror-switch-alignment

Conversation

@Nitjsefnie

Copy link
Copy Markdown
Contributor

What does this PR do?

Arms -Werror=switch on the six remaining Makefile compile lines that still omit it, so every $(CC)/clang compile line in the Makefile now carries the flag.

A correction to the premise first, because it changes what this PR is. You pre-approved this flag alignment in the #779 review against the asan / asan-http / tsan / valgrind lists plus build.sh. That work has already landed#786 (07d98e6, 2026-08-01) fixed exactly those four, and all three build.sh legs (:51, :61, :73) now carry the flag. build.sh is untouched here; there was nothing left to do in it.

So rather than open an empty PR, I audited every compile line in the Makefile. Six still omitted the flag:

line target what it compiles
110 FLAGS_poison the poison build variant
233 jit-smoke src/jit.c + src/jit_smoke.c
352 coverage all of $(SOURCES), -O0 --coverage
380 fuzz $(FUZZ_SOURCES) under ASan/UBSan
397 fuzz-libfuzzer $(FUZZ_SOURCES) under clang/libFuzzer
422 freestanding-libc-diff src/freestanding/mini_*.c + the diff harness

poison is the one I'd call a plain miss by #786 — it is the only member of VARIANTS (Makefile:113) still omitting the flag while all four of its debug-variant siblings carry it, and it existed at 07d98e6 (line 250 there). The other five are auxiliary targets rather than build variants, which is a fair distinction — happy to cut this back to just the FLAGS_poison line if you would rather keep the change strictly to variants; your call.

Line 359 ($(CC) --coverage -o $(BINARY) $(SOURCES:.c=.o)) is deliberately left alone — it links already-built objects and compiles nothing, so the flag would be a no-op. Lines 215/224/249/260/326/334 inherit it via $(CFLAGS), and 120/122 via FLAGS_<variant>.

No switch warning was surfaced anywhere — no C source needed changing. The -Wcomment / -Wformat-truncation warnings visible on some legs are pre-existing, a different warning class, and untouched here.

Before/after, from make -n:

### poison (compile of src/vm.c)
BEFORE: gcc -g -O1 -DEIGS_POISON ... -c src/vm.c -o build/poison/vm.o
AFTER:  gcc -Werror=switch -g -O1 -DEIGS_POISON ... -c src/vm.c -o build/poison/vm.o

### jit-smoke
BEFORE: gcc -Wall -Wextra -O2 -o /tmp/jit_smoke src/jit.c src/jit_smoke.c -lm
AFTER:  gcc -Wall -Wextra -Werror=switch -O2 -o /tmp/jit_smoke src/jit.c src/jit_smoke.c -lm

### coverage (per-source compile loop)
BEFORE: gcc -O0 -g --coverage -Wall -Wextra -c $src -o $obj
AFTER:  gcc -O0 -g --coverage -Wall -Wextra -Werror=switch -c $src -o $obj

### fuzz
BEFORE: gcc -g -fsanitize=address,undefined -o fuzz/fuzz_stdin
AFTER:  gcc -g -fsanitize=address,undefined -Werror=switch -o fuzz/fuzz_stdin

### fuzz-libfuzzer
BEFORE: clang -g -O1 -fsanitize=fuzzer,address,undefined -fno-sanitize-recover=all
AFTER:  clang -g -O1 -fsanitize=fuzzer,address,undefined -fno-sanitize-recover=all -Werror=switch

### freestanding-libc-diff
BEFORE: gcc -O2 -fno-builtin -ffp-contract=off -Wall -Wextra
AFTER:  gcc -O2 -fno-builtin -ffp-contract=off -Wall -Wextra -Werror=switch

Testing — all run with umask 022 at merge-base ae6a305af3f589a62e4fb6dbaa0e2890de8a2b22, all rc=0:

  • make poison — 24 TUs recompiled with the flag, linked clean
  • make jit-smoke — built and ran: JIT smoke: all cases passed.
  • make fuzz — clean
  • make fuzz-libfuzzer — clean under clang 17
  • make freestanding-libc-diff — built and ran: mini-libc differential: ALL SECTIONS PASS (glibc oracle)
  • coverage — its 24-TU compile loop and link run verbatim (both rc=0); I deliberately skipped the recipe's embedded run_all_tests.sh + gcov pass, which this flag cannot affect, and cleaned up with make coverage-clean
  • Full suite via ./build.sh: 3397/3397 passed, 0 failed

Follow-ups / Known Limitations

  • This class of miss will recur. build: carry -Werror=switch in build.sh and the sanitizer/valgrind legs #786 fixed the four legs it enumerated by name, and poison slipped through precisely because the sweep was a name list. A shared WARN_FLAGS variable, or a test asserting every $(CC) compile line in the Makefile carries the flag, would make it structural instead of manual. I did not add either here — out of scope for a flag alignment, but happy to send it if you want it.
  • fuzz-libfuzzer mirrors the OSS-Fuzz contract, where the real build takes $CFLAGS from the OSS-Fuzz environment. Adding the flag to the local clang line makes local reproduction stricter than the real build; it does not change what OSS-Fuzz does.
  • freestanding-libc-diff compiles src/freestanding/mini_*.c plus a tests/ harness rather than the runtime proper — the weakest fit for the word "variant" of the six, and the easiest to drop.

Checklist

  • make test passes locally — 3397/3397, 0 failed
  • New builtins have signature comments and docs in docs/BUILTINS.md — n/a, no builtins
  • New library functions follow conventions in docs/STDLIB.md — n/a, no library functions
  • New examples have a comment header explaining what they demonstrate — n/a, no examples
  • CHANGELOG.md updated (if user-facing change) — n/a, build-flag change with no user-facing effect

Generated by Claude Opus 5 (brief, implementation, review)

InauguralSystems#786 armed the sanitizer/valgrind legs and build.sh; the flag is now on
every $(CFLAGS) leg plus asan/asan-http/tsan/valgrind. Six hand-written
flag lists in the Makefile still omitted it, so a non-exhaustive switch
only warned when built through them:

- FLAGS_poison — the one entry in VARIANTS without it. Its siblings
  asan/asan-http/tsan/valgrind are all armed (InauguralSystems#786); poison predates that
  PR and was simply missed, so the uninit-read hunter build was the one
  debug variant where a new ValType/ASTType/opcode case only warned.
- jit-smoke  — compiles src/jit.c standalone against the smoke stubs.
- coverage   — compiles all of $(SOURCES) at -O0 --coverage.
- fuzz       — compiles $(FUZZ_SOURCES) under ASan/UBSan.
- fuzz-libfuzzer — same sources under clang/libFuzzer.
- freestanding-libc-diff — compiles src/freestanding/mini_*.c.

Every $(CC)/clang compile line in the Makefile now carries the flag; the
only remaining bare line is coverage's link step, which compiles nothing.
No other warning flag changed and no general -Werror is added.

All six legs build clean with the flag armed: make poison, jit-smoke (JIT
smoke all cases passed), fuzz, fuzz-libfuzzer (clang 17), and
freestanding-libc-diff (mini-libc differential ALL SECTIONS PASS); the
coverage leg's 24-TU compile loop and link both exit 0. No switch on any
of these paths is non-exhaustive. Suite 3397/3397 on the release build.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@InauguralPhysicist InauguralPhysicist left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. Verified on a local merge with current main: make -n poison shows the flag on the compile line, and make poison (24 TUs), make jit-smoke (all cases passed), and make freestanding-libc-diff (ALL SECTIONS PASS) all build and run clean — consistent with your no-source-changes claim, since any uncovered switch would now be a build error on those legs.

Keep all six — don't cut back to FLAGS_poison. The auxiliary targets compile the same closed-enum switches the variants do (fuzz compiles the whole runtime; jit-smoke compiles jit.c), and an exhaustiveness gate that skips the fuzzers is a gate with a hole in it. The variants-vs-auxiliary distinction was worth stating, but uniformity is the simpler invariant to keep true: every compile line carries it, no judgment call needed at the next audit.

And thank you for the premise correction — catching that #786 had already landed the pre-approved half and auditing the remainder instead of opening an empty PR is exactly the right move. You're also right that the class will recur; a make -n-based check that greps every emitted compile line for the flag would close it mechanically. If you want it, it's yours — otherwise I'll file it as a follow-up.

Merging. (Heads-up: my open #742 PR also touches the Makefile in different hunks; I'll rebase mine on top of this.)

@InauguralPhysicist
InauguralPhysicist merged commit e64acff into InauguralSystems:main Aug 2, 2026
16 checks passed
@Nitjsefnie

Copy link
Copy Markdown
Contributor Author

Taking the make -n check — I will send it rather than have you file it. Your steer on keeping all six is the right call and it makes the gate simpler to write: it can assert the uniform invariant directly (every emitted compile line carries the flag) instead of encoding a variants-vs-auxiliary judgment that would need re-litigating at the next audit. Noted on #742 — I will keep out of the Makefile until yours lands, then build on top of it.

InauguralPhysicist added a commit that referenced this pull request Aug 3, 2026
VERSION 0.35.0; CHANGELOG [Unreleased] -> [0.35.0] - 2026-08-02, with the
per-PR blocks consolidated into one Added/Changed/Fixed each (the shape
every prior release section uses). CLAUDE.md's "Latest release" line and
docs/llms.txt's version stamp move with it — doc_drift_check.sh rules 2,
3 and 5 gate all three, and the release build runs its own suite AFTER
the tag exists, so a stale line fails the release itself (#v0.27.0).

Four bodies of work had landed on main with no CHANGELOG entry at all and
are written up here rather than shipped silently:

- the dual-metric leak gate (#770) — uordblks for the arena class, RSS
  for the non-arena class, plus the /gate_nonce SO_REUSEPORT check
- #744 items 1-2 — the core->ext include edge and vm.c's 29 stale externs
- #739's close-out — g_model as a reasoned process-wide opt-out
- the lint-walker recursion train (#781-#785) — six W-rules that went
  blind inside unobserved: blocks and match arms

Also corrected: the #738 bullet's closing caveat said build.sh does not
carry -Werror=switch. True when written, false at release — #786 and #817
armed build.sh, the sanitizer/valgrind legs and the last six Makefile
flag lists, so the claim is now stated as the history it is and the
#786/#817 work has its own entry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

2 participants