← board

Cross-target codegen gaps (deferred v1 shortcuts)

Motivation

Collected smaller correctness/coverage gaps left as v1 shortcuts while bringing the managed runtime up on i386/ARM32/AArch64. Individually minor; several matter for the cross self-host and for not leaking memory.

Scope

  1. Managed aggregate locals on cross targets (record-with-managed-fields / variant / array-of-managed) — split out into its own ticket feature-cross-managed-aggregate-locals on 2026-06-13 once it grew into a multi-part sub-arc (prologue zero-init + body ARC + epilogue release). It is the next arm32 compiler.pas wall (parser line 13288). Scalar managed-local release at scope exit (the smaller leak-only part) is folded into that ticket's epilogue item.
  2. Copy-on-write on dynamic-array writesIR_LEA of a dyn-array in write mode currently loads the handle without PXXDynArrayUnique, so a shared array (a := b; a[i] := x) mutates both. Wire the COW call on cross targets.
  3. Class instantiationT.Create (VMT setup + constructor dispatch) errors on i386/ARM32/AArch64 (class instantiation not yet supported). Port the -Ord(tkGetMem) class path + IR_VIRTUAL_CALL.
  4. AArch64 literal+literal tyString inline concat — the 272-byte-buffer path segfaults (a codegen bug); reverted to deferred. ansistring-rooted concat works. Retry against ir_codegen_arm32.inc lines ~434-468.
  5. by-ref managed-string / var-array params on cross targets — partial; SetLength on a var array param and some by-ref string stores error.
  6. Float params/results + full builtin unit on i386/ARM32 (moved here from feature-cross-float-variant, 2026-06-12) — the 32-bit internal call ABI passes every argument as one 4-byte slot, so procedures with Double params or results are rejected; that in turn blocks compiling the full builtin unit (Str/Val/FloatToStr) on those targets. Float expressions, writes, and variants work (served from builtinheap). Ties into feature-cross-param-abi. Variant locals are a related gap: 16-byte zero-init of frame slots errors on all cross targets (globals work).
  7. SetLength on a managed AnsiString — the cross backends only accepted an IR_LEA (dyn-array) SetLength target and errored on SetLength(ansistring,n) (SetLength expects an array variable). arm32 done via the new portable PXXStrSetLen runtime helper (builtinheap.pas). i386 + aarch64 still need the same one-block wiring (the helper is shared; they currently fail earlier walls before reaching SetLength when compiling compiler.pas).
  8. Managed-string Length and char-indexing on cross targetsLength(s) and s[i] on a managed AnsiString returned garbage / 0 on arm32: IR_LEA of a scalar ansistring yielded the slot address, not the auto-loaded heap handle, so the [handle-8] length read and the data-pointer index base were wrong. arm32 done — IR_LEA now loads the handle (slot content) for a scalar ansistring in read mode (not InLValueWrite), keeping the slot address in write mode, mirroring the x86-64 gate. i386/aarch64 likely share the gap (unverified; they fail earlier walls first).
  9. in set-membership operator on cross targetsx in [items] errored on arm32 (builtin/special call not yet supported, specialId SPECIAL_IN). arm32 done — emits a constant compare-chain (single members + lo..hi ranges) accumulating membership via conditional execution, no materialised set. i386/aarch64 likely share the gap (they fail earlier walls first).

Acceptance

Each item has a focused cross test (oracle vs x86-64); the v1 shortcut is removed. Can be closed incrementally — split into sub-tickets if a single item grows large.

Log

Closure (2026-06-16)

feature-cross-bootstrap-selfhost is DONE — byte-identical self-fixedpoint on i386/aarch64/arm32 (and x86-64). This ticket existed to unblock that gate, so its blocking purpose is met: every code path compiler.pas itself exercises now works byte-identically on all cross targets. Residual gaps are only in language features the compiler does NOT self-use (e.g. classes, interfaces, some param/ ABI shapes user code hits) — those move to the language-surface hardening effort driven by the synthetic conformance harness ([[feature-synthetic-feature-matrix-test]]). Closed.

Closing commits: rolled up under the cross self-host bootstrap — 65921c1 (cross self-host bootstrap DONE i386+aarch64+arm32), 5b0e3c0 (cross-bootstrap gates), ca0b8df (bootstrap restore). Per-item fixes logged with their dates above.