A missing runtime helper silently skips its action in 38 places
grep -n -A1 "FindProc('...')" compiler/*.inc, filtered to a following
if ... < 0 then Exit (or begin Result := -1; Exit; end), gives 38 sites
on 2026-09-29: 18 on the Pascal side and 20 in pyparser.inc.
How it bit
5ebf185c24 clamped a variable SetLength count through builtin's
PXXShortLenClamp and skipped the clamp when FindProc returned -1. A program
with no uses clause loads builtin only when a pre-scan trigger name appears
(pasparser_prog.inc). frankd-90's var t: string[10]; n := 50; SetLength(t, n) + fill segfaulted on the tip; adding HexStr anywhere made it pass. Both
fixtures called HexStr, so they were green for the wrong reason. Fixed inline
(no helper) with test_setlength_clamps_with_no_builtin_in_the_program, whose
negative control fails on the pushed tip e0b85a7460.
Triage of the Pascal-side sites (unprobed)
Guards a CORRECTNESS or SAFETY action. Probe these first:
| site | helper | skipped action if absent |
|---|---|---|
| ir.inc IRWrapNilChk | PXXNilRef | the nil check itself |
| ir.inc IREmitCaughtExcFree | PXXObjFree | freeing a caught exception object (leak) |
| pasparser_call.inc EmitMainBodyIntfTempRelease | PXXIntfRelease | releasing main-body interface temps (leak) |
| ir.inc IRStrUniqueForByRefElem | PXXStrUnique | copy-on-write before a var-param element write (aliasing) |
| ir.inc IRClassMatchRuntime | __pxxInheritsFrom | runtime class match (what does the caller fall back to?) |
| pasparser_stmt.inc GenMakeDestroyCall | __pxxTObjectDestroy | the destructor on Free (MEASURED OK: builtinheap is pulled in for classes; a no-uses program's TObject(p).Free runs the override) |
Probably legitimately optional (feature absent, and so is its use): PromoWidenToDouble (PXXPromoToDouble, "promocore not loaded"), IRDropManagedResult and SLReleaseLocalsAtDone (PXXObjRelease, NilPy object model), IRPyVarEqTry (pyvar_eqv), GenMakeClassRefOp's __pxxClassName family, GenMakeGetInterfaceCall (__pxxGetInterface): all should be checked for what the caller does with -1.
The 20 pyparser.inc sites are NilPy runtime lookups (pyvar_, pyclsattr_, PyNotSubscriptable, ...). pylib/pyeval are always loaded in a NilPy program, so absence there is likely a build-configuration question, not a program- shape one.
What to do
For each site: write the smallest default-profile program that reaches it
without naming anything that pulls the helper's unit in, then check the output.
Where it can be reached, either pull the unit in (a pre-scan trigger) or make
it an Error naming the helper. Do not blanket-convert: --no-default-rtl (the
compiler's own build) and the ESP bare profile legitimately lack some helpers,
and gate quick doesn't build every profile.