← board

SetLength expects a string variable in IR codegen on a valid array SetLength

Resolution (2026-06-22): NOT slot/offset allocation and NOT method-complexity. Root cause was a named dynamic-array alias used as a class field (FOps, FArgs: TIntArray; FLabelName: array of AnsiString is inline and was fine): the named-type field parse branch never set fIsDyn/fDynDepth, so UFldDynDepth = 0 and SetLength misrouted to the string path. The "small reduction compiles" cases all used inline array of T fields or local arrays (never broken) — that's why it looked complexity-sensitive. Fixed by recording the alias's dyn-depth on the field (4a37b00); see the done ticket. examples/vm/vmdemo.pas is ALL OK on v35.

Summary

A valid SetLength on a dynamic-array variable is rejected at IR codegen with:

pascal26:274: error: SetLength expects a string variable in IR codegen ()

The code is correct: FPC compiles and runs it to ALL OK. PXX only fails in a sufficiently complex method — extracted into a small method the same SetLength compiles fine, so this is layout / context-sensitive, the same flavour as bug-impl-prescan-codegen-regression (and likely the same root in local/temp slot allocation), but here it surfaces as a SetLength IR type-check failure rather than silent wrong codegen.

The offending SetLength targets either an array of AnsiString field (FLabelName) or array of Integer fields (FOps/FArgs) inside TMachine.Assemble (a ~16-local method with nested loops and several other SetLengths). The "expects a string variable" wording suggests the SetLength lowering picks the wrong element-kind path for the target in this context.

Repro (reliable, FPC-verified)

# PXX: rejected
stable_linux_amd64/default/pinned -Fulib/rtl examples/vm/vmdemo.pas /tmp/vm
#   -> pascal26:274: error: SetLength expects a string variable in IR codegen ()

# FPC: compiles + runs ALL OK (loopsum 55, factiter 120, factrec 120, subr 36/81)
cp lib/rtl/vm.pas /tmp/vm.pas; cp examples/vm/vmdemo.pas /tmp/vmdemo.pas
fpc -Mobjfpc -Fu/tmp /tmp/vmdemo.pas -o/tmp/vmf && /tmp/vmf

lib/rtl/vm.pas is the clean, Platonic repro — left in the tree exactly as written (no workaround). The trigger is global-layout-sensitive: a hand-reduced class method with the same field types + SetLength pattern + ~12 locals compiles fine, so a small standalone repro is elusive; use the full unit.

Isolated cases that DO compile (for contrast)

So neither the field type nor the SetLength pattern alone is the bug; method complexity tips it over.

Likely area

SetLength IR lowering: element-kind selection (string vs non-string managed vs plain) reads stale/clobbered type info when the target's slot allocation is under pressure from many locals/temps. Tie-in with bug-impl-prescan-codegen-regression (same suspected slot/offset subsystem).

Impact

feature-demo-vm is parked in blocked/: code complete + FPC-verified, but PXX cannot compile it, so it is NOT wired into make lib-test. Unblocks when this (and the related slot/offset bug) is fixed.

Log

Resolved (v35)

Duplicate of bug-named-dynarray-field-setlength (fixed by Track A, pinned v35). examples/vm/vmdemo.pas compiles + runs ALL OK on v35 with the clean source unchanged. Closed.