Files
BFM-decomp/tools
Drew T abbedcee8b fix(phase-26a): A9a — canon_sig_reconcile sees fn-ptr dispatch tables (cdecl supplement)
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.
2026-07-14 19:59:56 -06:00
..