← board

A parameterless method is undefined variable as a by-ref argument

The bug

FE.MC(Cur);          { undefined variable (Cur) }

where Cur is a parameterless function method of the ENCLOSING class and MC takes const p: TRec. Measured boundary — everything else compiled:

spelling result
q := Cur OK
Own(Cur) — argument to an own unqualified method OK
Free1(Cur) — argument to a free routine OK
Cur.Row — field of the bare result OK
FE.MC(Self.Cur) — explicit Self OK
FE.MC(Add(A, B)) — a call EXPRESSION OK
FE.MVal(CurI) — by-VALUE parameter OK
FE.MC(Cur) undefined variable (Cur)
FE.MTwo(1, Cur) same, any position

So the affected door is exactly the argument list of a call on a qualified receiver, at a by-ref parameter — the one path with no implicit-Self arm anywhere on it.

Mechanism

ByRefArgStartsExpression (pasparser_call.inc) decides whether a by-ref argument may be an expression or must be a bare lvalue. Answering False forces ParseLValueAST(FindSym(name), …), and FindSym of a method name is -1, so the argument came out as an undefined variable. Two independent reasons it answered False here:

  1. The callee-name lookup was free-functions-only. The clause that already recognises a bare parameterless FUNCTION (FindProc) has no method spelling, so a method name missed both lookups.
  2. The gate enumerated const TYPES. ParamBindsAnExpression was const Variant OR const array of T. A const <record> is by-ref because a record is and const because it is written const, and it was in neither arm.

Fix

Two edits, both in compiler/pasparser_call.inc:

Why not a third implicit-Self arm. ParseFactorCore has one and ParseLValueAST's unresolved-name path has none, and the note-to-self on the corpus ticket said to mirror rather than add a third — two entries are why [the sibling] bug survived one fix. Routing the argument to ParseExpr instead reuses the arm that already exists, so the count of implicit-Self dispatchers does not go up.

Measured

The remaining rung-7 wall is NOT this

pparser.pp:778 raise ENotSupportedException.Create(SErrMultipleSourceFiles) — an RTL exception class lib/rtl does not declare. Pre-existing: it is in the baseline's 5 errors too, and the compiler's in: line misattributes it to pscanner.pp, which is this corpus's standing coordinate problem and not a new one. Separate work, separate lane (B/RTL).

Guards

Log

Both cross-reference the free-function twins ([[bug-p-a-parameterless-function-is-undefined-as-a-method-call-argument]]), and those two now cross-reference back.