mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-26 13:33:34 -04:00
abbedcee8b
The def-side-wall recovery tool, live on the ×134 economic-engine paths (jtbl_family_bank,
family_sweep --reconcile-raw, bank_exemplar, t7_bank, scope_data_externs, family_remap). The
audit's two HIGH findings: its tu_ambient/visible_above classifier regexes and _reconcile_data's
_DATA_EXTERN_RE have a type class `[\w \*]` that cannot hold a `(`, so they are 100% blind to
fn-ptr DATA decls — `extern void (*D_x[])(void);`, the per-overlay jump-table DISPATCH arrays
jtbl_family_bank exists to bank. A fn-ptr symbol thus landed in NO bucket, fell out of `visible`,
and _reconcile_data block-moved the draft's extern into a guaranteed `conflicting types`.
FIX (R33-adjacent, but SUPPLEMENT not wholesale-replace — the proven regex stays byte-identical):
- tu_ambient / visible_above: keep the v3.2 regex classification UNCHANGED, then supplement from
cdecl.tu_scope with ONLY the fn-ptr symbols the regex drops (_fnptr_data). A full delegation was
tried and rejected — cdecl normalizes funcs formatting (void*→void *, param names, and a real
return-ptr hazard u8*→u8) which rippled 728k value-changes into the callee string-compare; the
audit flagged fn-ptr DATA, not funcs, so the blast radius is held to exactly that.
- _reconcile_data: a fn-ptr pre-pass (_FNPTR_DATA_RE) — visible ⇒ STRIP (ambient serves; a
call-through `D_x[i]()` is decl-INDEPENDENT indirect codegen, so NO access-cast: casting a
fn-ptr would mangle it into `((u8*)D_x)[i]()`, the dormant transform reconcile_tu documents);
not visible ⇒ block-move verbatim. Plus the F2 fix (bail on a `(` in the CODE, not a comment).
- R32 coverage assertion: a fn-ptr data extern may never survive the pass.
PROVEN ADDITIVE (regression baseline .run/audit/a9a_*):
- classifier snapshot over 1683 TUs: REGRESSIONS 0, ADDITIONS 69,798 (all data fn-ptr).
- reconcile() OLD-vs-NEW over 434 real drafts against home TUs: 0 regressions.
- src/ UNTOUCHED (a tool change moves no bytes); the whole-binary byte-gate (G3/P9) remains the
sole arbiter — a wrong reconcile fails to bank, never falsely banks.