← board

An integer argument binds a procedural overload over an exact integer one

The fact

Measured 2026-09-07, and on pin v407, against fpc 3.2.2:

type TCmp = function(a, b: Pointer): Integer;
  TC = class
    procedure SetCmp(c: TCmp);     overload;
    procedure SetCmp(n: LongInt);  overload;
  end;
...
  SetCmp(4);
fpc 3.2.2 cmp n 4 — the LongInt overload
pxx cmp set — the PROCEDURAL overload

An exact parameter match lost to a procedural one. Both candidates have the same arity, so this is a ranking question and not an arity one.

Why it is worse than a wrong branch

The integer is bound to a parameter the callee may CALL. Here the body only tests c = nil, so 4 is merely printed as "set"; a body that invoked c(a, b) would jump to address 4. Nothing in the chain is checked — no diagnostic, and the failure surfaces as a wild jump far from the call site, which is this repo's expensive class.

Where to look

OverloadArgRank (pasparser_call.inc) ranks by TTypeKind pair. A procedural parameter's stored kind and an integer argument evidently do not reach rank 3, and an exact tyInteger/tyInteger pair should be rank 0 — so either the procedural parameter's stored kind is not what the ranker thinks, or both candidates tie and declaration order decides. Print the two ranks before theorising; that is what PXXDBG exists for.

Note the class-identity and pointer-element refinements immediately below the rank call: both were added for exactly this shape (two parameters that tie at rank 0 and get picked by declaration order). A procedural parameter looks like a third instance of that pattern, which would make the fix a third refinement in the same place rather than a new mechanism.

How it was found

Writing the positive half of bug-p-a-bare-method-overload-call-accepts-any-argument-type-and-runs-the-first-body, where a same-arity sibling had to be put beside a procedural parameter to force the multi-candidate path. The row is deliberately ABSENT from test/test_method_overload_arg_typecheck_ok_multi.pas with a comment saying why: recording today's wrong answer as expected output would turn that fixture RED the day this is fixed.

Log