[fpc-devel] Wrong code generation bug in FPC 3.2.3 (likely 324RC too)

Martin Frb lazarus at mfriebe.de
Fri Oct 3 21:02:47 CEST 2025


Likely affecting the RC too / Found in 3.2.3 420f7af213

There is an issue in the code generator.
Under some circumstances inlined code will use the same physical memory 
in its stackframe for one of its own locals (params), as the containing 
code does use for one of its locals.

Actually, it overwrites the local var of the caller, that is the var the 
caller passed as arguments. So it behaves as if the param was a "var 
param" => but it is not...

This happens
- with peephole disabled. / also happens with its enabled.
- opt regvar can also be enabled or disabled


The following code is inlined

function TGenLazRoundList.GetItemPointerFast(Index: Integer): TPItemT;
var
   c: Cardinal;
   MPtr: TLazListClassesInternalMem.PMemRecord;
begin
   MPtr := FMem.FMem;
   assert(Cardinal(Index) <= MPtr^.Capacity, 
'TGenLazRoundList.GetItemPointerFast: Index <= c');
   Index := MPtr^.FirstItem.Idx + Index;
   c := MPtr^.Capacity;
   if Cardinal(Index) >= c then
     Index := Index - c;
   Result := TPItemT(@MPtr^.Data + Index * FItemSize.ItemSize);
end;


The outer function (inlining the above) is also inlined, into its caller)

The caller does

     PSource := PByte(ItemPointerFast[Cnt]);

And when GetItemPointerFast does
   Index := MPtr^.FirstItem.Idx + Index;

then the memory in which the caller has its copy of "cnt" changes


----
More to follow.

I will be away most of next week.
I will try to get a snapshot for testing.




More information about the fpc-devel mailing list