Anonymous function variable capture getting stale record fields and not updating them, but a capture of function parameters are able to be updated.
## Summary When capturing and updating record fields stale values are captured in an anonymous function. Record fields updated in the anonymous function are not reflected outside the anonymous function. ## System Information - **Operating system:** Linux, AlmaLinux 9.1 x86_64 - **Processor architecture:** x86_64 - **Compiler version:** 3.3.1-12241-gcf41a549b9 - **Device:** Computer ## Steps to reproduce Given this program: ```pascal {$mode objfpc}{$H+} {$modeswitch AnonymousFunctions} {$modeswitch FunctionReferences} {$modeswitch AdvancedRecords} program noupdate; uses sysutils; type prtype1int = reference to procedure(i: integer); TSomeRec = record strict private a: integer; b: integer; procedure update; procedure update10; procedure update20; public class procedure main10; static; class procedure main20; static; end; procedure TSomeRec.update; procedure primary(i: integer = 0); begin for i := 0 to b do inc(a); end; begin primary; end; procedure TSomeRec.update10; procedure primary(i: integer = 0); begin for i := 1 to b do inc(a); writeln('update10 a = ', a); end; begin update; b += 4; primary; end; procedure TSomeRec.update20; procedure primary(const f: prtype1int); begin f(0); end; begin writeln('update20.0 a = ', a, ' b = ', b); update; b += 4; writeln('update20.1 a = ', a, ' b = ', b); primary(procedure (i: integer) begin writeln('update20.2 a = ', a, ' b = ', b); for i := 1 to b do inc(a); writeln('update20.3 a = ', a, ' b = ', b); end); end; class procedure TSomeRec.main10; static; function primary: TSomeRec; begin result.a := 0; result.b := 10; result.update10; end; begin writeln(format('main10 a = %d', [primary.a])); end; class procedure TSomeRec.main20; static; function primary: TSomeRec; begin result.a := 0; result.b := 10; result.update20; end; begin writeln(format('main20 a = %d', [primary.a])); end; procedure primary(const n: integer=0; i: integer=0; a: integer=0); begin writeln('primary a = ', a); for i := 1 to n do procedure begin a += 1; end(); writeln('primary a = ', a); end; procedure main; begin TSomeRec.main10; TSomeRec.main20; primary(10); end; begin main; end. ``` Which compiles: ```shell $ fpc noupdate.pas Free Pascal Compiler version 3.3.1 [2022/12/26] for x86_64 Copyright (c) 1993-2022 by Florian Klaempfl and others Target OS: Linux for x86-64 Compiling noupdate.pas Linking noupdate 102 lines compiled, 0.2 sec, 376304 bytes code, 167256 bytes data ``` When runs produces the following output: ```shell $ ./noupdate update10 a = 25 main10 a = 25 update20.0 a = 0 b = 10 update20.1 a = 11 b = 14 update20.2 a = 0 b = 10 update20.3 a = 10 b = 10 main20 a = 11 primary a = 0 primary a = 10 ``` ## Example Project See Steps to reproduce. ## What is the current bug behavior? See Steps to reproduce. It seems the capture in **`TSomeRec.update20`** is picking up stales value of *`b`* and *`a`*, and not updating *`a`*. ## What is the expected (correct) behavior? I would expect **`TSomeRec.update20`** to behave the same as **`TSomeRec.update10`**. The global **`primary`** procedure shows that capture variables can be updated. ## Relevant logs and/or screenshots See Steps to reproduce. ## Possible fixes None known.
issue