← board

A routine assigned to a procedural type of another calling convention is accepted

type TF = function(x: Double): Double; cdecl;
function Twice(x: Double): Double; begin Twice := x * 2; end;
var f: TF;
begin f := @Twice; WriteLn(f(21.0):0:1); end.   { 0.0 on x86-64, Nan on i386 }

FPC 3.2.2 rejects it: Incompatible types: got "<address of function(Double):Double;Register>" expected "<procedure variable type of function(Double):Double;CDecl>".

Fix

ProcAddrConventionMismatch in ir.inc compares ProcCdecl of the destination's procedural signature with CProcUsesCAbi of the routine. It is asked at both sinks:

It is the same pair of sites as the call-result check next to it. External routines are exempt, because their convention is the library's. C and Nil Python programs are exempt, like the sibling checks.

Not covered: a wider gap

An arity or parameter-type mismatch (f := @Two where Two takes two Doubles) still compiles in default mode, and FPC refuses it too. That is a general procedural signature check. It is not done here, because it would reach further into existing programs, and it needs its own measurement.

Test

Rows in test-core (x86-64) and test-i386.