2.8 KiB
§68 — A comment-only line halted the extern scan, and the skip label blamed the type cap (Phase 29 SESSION-18)
dedup_propagate.find_site() extracts a matched body as "preceding contiguous externs .. closing
brace". Its backward walk skipped blank lines but not comment-only lines. So a body written
like this — which is ordinary house style — silently lost its first extern group:
extern s16 D_80126940; /* <- DROPPED: everything above the comment */
extern s16 D_80126942;
/* ------------------------------------------------ */ /* <- the walk stops HERE */
extern s32 func_80012ABC(s32, s32, s32); /* <- only these were carried */
s32 func_80174CB0(s32 param_1, s32 param_2) { … }
The truncated body then failed compiles_standalone() on the now-undeclared symbols — and the caller
filed every such failure under "overlay-local TYPE (the real cap)".
That label is why the class went unfixed for ~4 phases. The Phase-21 backlog already carried the right answer — "a macro-extern-injection (or canonical-callee-sig embed) frees them ×134 (~+0.3%)" — but every session after that read the skip line, saw "the real cap", and treated it as the known-hard overlay-local-type wall. A diagnostic that discards its cause is invisible work (R32); one that asserts the WRONG cause actively redirects everyone who reads it.
Two fixes, both small:
compiles_standalone()returns(ok, stderr); the caller classifies by actual cc1 output —missing file-scope extern (CARRY-FIXABLE): <names>vsoverlay-local TYPE (the real cap).- the backward walk treats comment-only lines like blanks, and the emitted body filters them out so
make_macronever meets a//.
Result: func_80174CB0 went from "not self-contained (local types)" to a 138-member plan.
⚠️ "CARRY-FIXABLE" is NOT one cause — measured. After fix (2), the 7 skipped functions in
ov_SC01_077 (0x8016A73C 0x80155800 0x80167540 0x801535F4 0x8016F0AC 0x80142B2C 0x8014FE60) are
still blocked, so at least one more sub-class exists: their missing symbols are not adjacent to the
def at all (e.g. D_801152A8 appears 26× in engine_core.h but only ever INSIDE DEFINE_func_*
macro bodies, never at file scope). Those need the genuine carry mechanism — collect the referenced
file-scope decls wherever they live (cdecl.scope() is the right oracle, R33) and emit them inside
the lifted macro. Do not assume fix (2) cleared the queue: re-run
--auto-from <ov> --check-only and read the per-class counts.
The general lesson: when a tool refuses, make it print what the compiler said, not what the
author guessed the compiler meant. Every wrong-label bug in this project (§53's carve, the 193
listCdBuffer slices, masked_diff's 150 closeness lies, this one) had the true cause available and
threw it away.