blaise/compiler
Graeme Geldenhuys a4d178b52c fix(codegen): itab dispatch of a record-returning method (both backends)
An interface (itab-dispatched) method returning a RECORD was broken on both
backends, both when the result was assigned and when discarded in statement
position, for memory-class (sret) and register-class records alike.  The itab
dispatch had no record-return ABI: it emitted a scalar call, so for a
memory-class return the first argument register doubled as the sret pointer
(the callee received a garbage argument and wrote the record over caller
memory — "_StringRelease corrupted header"), and a register-class return was
dereferenced as a pointer.  Assignment was equally broken because
IsRecordCall / IsNativeRecordCall keyed off ResolvedMethod, which is nil for
itab dispatch.

QBE:
* IsRecordCall recognises an itab record call (ResolvedClassType = interface +
  ResolvedType in [record, static-array]) for both the args form
  (TMethodCallExpr) and the zero-arg form (TFieldAccessExpr.IsInterfaceCall).
* EmitIntfSretDispatch builds the visible args (Self, method args) and delegates
  to EmitRecordReturnCallSite, which applies the correct ABI from
  ClassifyRecordReturn (sret pointer vs register capture) — instead of always
  passing an sret buffer.
* The discarded-statement path (EmitMethodCall) gained a record/static-array
  branch: a throwaway zeroed buffer, the classified call, then
  EmitRecordReleaseFields on the buffer.

Native:
* IsNativeRecordCall recognises the itab record case.
* New EmitIntfRecordSretDispatch performs itab dispatch with the full
  record-return ABI: an sret buffer in %rdi for a memory-class record, or
  EmitRecordRegReturnCapture (a new helper covering rcInt1/rcInt2/rcSSE1/
  rcSSE2/rcIntSSE/rcSSEInt) storing the register result into the destination.
  Wired into EmitRecordCallSretAt, both record-assignment branches (implicit-Self
  field and plain local/var/global), and the discarded-statement path.

E2E regressions (both backends, via AssertRunsOnAll):
TE2EInterfaceTests.TestRun_InterfaceMethod_ReturnsSretRecord and
_ReturnsRegisterRecord — each exercises an assigned and a discarded call.
2026-06-27 21:52:23 +01:00
..
src fix(codegen): itab dispatch of a record-returning method (both backends) 2026-06-27 21:52:23 +01:00
project.xml refactor(rtl): relocate RTL units into the compiler tree (dotted-flat names) 2026-06-25 16:05:44 +01:00