build: carry -Werror=switch on the six remaining Makefile compile lines - #817
Conversation
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
left a comment
There was a problem hiding this comment.
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.)
|
Taking the |
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>
What does this PR do?
Arms
-Werror=switchon the six remaining Makefile compile lines that still omit it, so every$(CC)/clangcompile 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/valgrindlists plusbuild.sh. That work has already landed — #786 (07d98e6, 2026-08-01) fixed exactly those four, and all threebuild.shlegs (:51,:61,:73) now carry the flag.build.shis 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:
FLAGS_poisonpoisonbuild variantjit-smokesrc/jit.c+src/jit_smoke.ccoverage$(SOURCES),-O0 --coveragefuzz$(FUZZ_SOURCES)under ASan/UBSanfuzz-libfuzzer$(FUZZ_SOURCES)under clang/libFuzzerfreestanding-libc-diffsrc/freestanding/mini_*.c+ the diff harnesspoisonis the one I'd call a plain miss by #786 — it is the only member ofVARIANTS(Makefile:113) still omitting the flag while all four of its debug-variant siblings carry it, and it existed at07d98e6(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 theFLAGS_poisonline 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 viaFLAGS_<variant>.No switch warning was surfaced anywhere — no C source needed changing. The
-Wcomment/-Wformat-truncationwarnings visible on some legs are pre-existing, a different warning class, and untouched here.Before/after, from
make -n:Testing — all run with
umask 022at merge-baseae6a305af3f589a62e4fb6dbaa0e2890de8a2b22, all rc=0:make poison— 24 TUs recompiled with the flag, linked cleanmake jit-smoke— built and ran:JIT smoke: all cases passed.make fuzz— cleanmake fuzz-libfuzzer— clean under clang 17make 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 embeddedrun_all_tests.sh+gcovpass, which this flag cannot affect, and cleaned up withmake coverage-clean./build.sh: 3397/3397 passed, 0 failedFollow-ups / Known Limitations
poisonslipped through precisely because the sweep was a name list. A sharedWARN_FLAGSvariable, 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-libfuzzermirrors the OSS-Fuzz contract, where the real build takes$CFLAGSfrom 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-diffcompilessrc/freestanding/mini_*.cplus atests/harness rather than the runtime proper — the weakest fit for the word "variant" of the six, and the easiest to drop.Checklist
make testpasses locally — 3397/3397, 0 faileddocs/BUILTINS.md— n/a, no builtinsdocs/STDLIB.md— n/a, no library functionsGenerated by Claude Opus 5 (brief, implementation, review)