Skip to content

Local variable trashing `-gt` trashes anonymous function values in arguments

Summary

When an anonymous function is passed as an argument, that argument is treated as uninitialized by local variable trashing and is overwritten with the signal pattern. If the argument is passed a nil value, that does not happen.

System Information

  • Operating system: Windows
  • Processor architecture: x86, x86-64
  • Compiler version: fpc-3.3.1-899981 (2022-07-31)

Steps to reproduce

Run the code below with fpc -gt.

Example Project

{ %OPT = -gt }

program Project1;

{$mode objfpc}{$H+}
{$ModeSwitch anonymousfunctions}
{$ModeSwitch functionreferences}

type
  TProc = reference to procedure;

procedure problem(aParam1: integer; aParam2: integer; aParam3: TProc);
begin
  Writeln(aParam1, aParam2);
end;

procedure noproblem(aParam1: integer; aParam2: integer; aParam3: IUnknown);
begin
  Writeln(aParam1, aParam2);
end;

procedure test;
begin
  noproblem(1, 2, TInterfacedObject.Create);            // ok
  problem(3,4, nil);                                    // ok
  problem(5,6, procedure begin Writeln('x'); end);      // aParam3 is trashed
end;

begin
  test;
end.

What is the current bug behavior?

The first two calls succeed, the third receives a SEGV in the function prologue's fpc_intf_incr_ref due to the value of aParam3 being overwritten. Passing "normal" interfaced objects works, so I assume something doesn't recognize anonymous function instances.

What is the expected (correct) behavior?

All three should succeed, printing:

12
34
56
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information