management operators double free after nested function
## Summary finalize is called twice if the record is used in a nested function ## System Information <!-- The more information are provided the easier it is to replicate the bug --> - **Operating system:** Ubuntu 22.04 - **Processor architecture:** x86-64 - **Compiler version:** 3.3.1 36a2835f8c95290fbd3002700726d4bfb2ac006c LLVM ## Example Project ``` program Project1; {$mode objfpc}{$ModeSwitch arrayoperators}{$ModeSwitch advancedrecords} uses sysutils; type IXQValue = record //something like a smart pointer x: pinteger; class operator initialize(var xx: IXQValue); class operator finalize(var xx: IXQValue); class operator addref(var xx: IXQValue); class operator Copy(constref s: IXQValue; var xx: IXQValue); class function create: IXQValue;static; end; class operator IXQValue.initialize(var xx: IXQValue); begin xx.x := new(pinteger); xx.x^ := 1; end; class operator IXQValue.finalize(var xx: IXQValue); begin dec(xx.x^); writeln(inttohex(ptruint(@xx),8), ' ',inttohex(ptruint(xx.x),8), ' ', xx.x^); // if xx.x^ = 0 then dispose(xx.x); end; class operator IXQValue.addref(var xx: IXQValue); begin inc(xx.x^); end; class operator IXQValue.Copy(constref s: IXQValue; var xx: IXQValue); begin inc(s.x^); write(' copy '); //finalize(xx); // writeln(inttohex(ptruint(@xx),8), ' ',inttohex(ptruint(xx.x),8)); dec(xx.x^); writeln(inttohex(ptruint(@xx),8), ' ',inttohex(ptruint(xx.x),8), ' ', xx.x^); xx.x := s.x; end; class function IXQValue.create: IXQValue; begin //result := default(IXQValue); end; function test(const previous: IXQValue): IXQValue; var newList: IXQValue; {$define doublefree} {$ifdef doublefree} procedure print(const v: IXQValue); var temp: IXQValue; begin writeln(newList.x^); end; {$endif} var i: SizeInt; resultList: IXQValue; tempList: IXQValue; begin resultList:=ixqvalue.create; newList := ixqvalue.create; newlist := ixqvalue.create; tempList := newList; resultList := tempList ; writeln(result.x^); writeln('newList: ',inttohex(ptruint(@newList), 8)); writeln('tempList: ',inttohex(ptruint(@tempList), 8)); result := resultList; end; begin test(ixqvalue.create); end. ``` ## What is the current bug behavior? ``` copy 7FFC27A36C78 7F4ACA41B140 0 copy 7FFC27A36C78 7F4ACA41B1C0 1 copy 7FFC27A36C80 7F4ACA41B180 0 copy 7FFC27A36C98 7F4ACA41B160 0 1 newList: 7FFC27A36C78 tempList: 7FFC27A36C80 copy 7FFC27A36CD8 7F4ACA41B100 0 7FFC27A36CA0 7F4ACA41B1A0 4 7FFC27A36CA8 7F4ACA41B1C0 0 7FFC27A36C78 7F4ACA41B1A0 3 7FFC27A36C78 7F4ACA41B1A0 2 7FFC27A36C98 7F4ACA41B1A0 1 7FFC27A36C80 7F4ACA41B1A0 0 7FFC27A36CD8 7F4ACA41B1A0 -1 7FFC27A36CE0 7F4ACA41B0E0 0 7FFC27A36CD8 7F4ACA41B1A0 -2 ``` Finalize is called twice on 7FFC27A36C78 ## What is the expected (correct) behavior? only call finalize once The counter should not become -2 (not sure if -1 is correct at the end)
issue