LLVM: fix double init/fini of local managed variables accessed from nested functions

resolves #40392
This commit is contained in:
Jonas Maebe 2023-09-14 15:02:11 +02:00
parent 5676cf4c1a
commit c96641f901
2 changed files with 66 additions and 2 deletions

View File

@ -239,7 +239,7 @@ implementation
if (target_info.system in systems_fpnestedstruct) and
(p.nodetype=loadn) and
(tloadnode(p).symtableentry.typ=localvarsym) and
(tloadnode(p).symtableentry.visibility=vis_hidden) then
tlocalvarsym(tloadnode(p).symtableentry).inparentfpstruct then
begin
p.free;
result:=cnothingnode.create;
@ -288,7 +288,7 @@ implementation
if (target_info.system in systems_fpnestedstruct) and
(p.nodetype=loadn) and
(tloadnode(p).symtableentry.typ=localvarsym) and
(tloadnode(p).symtableentry.visibility=vis_hidden) then
tlocalvarsym(tloadnode(p).symtableentry).inparentfpstruct then
begin
p.free;
result:=cnothingnode.create;

64
tests/webtbs/tw40392.pp Normal file
View File

@ -0,0 +1,64 @@
{$mode objfpc} {$modeswitch advancedrecords}
{ define doublefree}
var
InitCount: int32 = 0;
type
ManRec = record
x: int32;
class operator Initialize(var self: ManRec);
class operator Finalize(var self: ManRec);
class operator Copy(constref b: ManRec; var self: ManRec);
class operator AddRef(var self: ManRec);
end;
class operator ManRec.Initialize(var self: ManRec);
begin
inc(InitCount);
end;
class operator ManRec.Finalize(var self: ManRec);
begin
dec(InitCount);
end;
class operator ManRec.Copy(constref b: ManRec; var self: ManRec);
begin
writeln('shouldn''t happen');
halt(1);
end;
class operator ManRec.AddRef(var self: ManRec);
begin
writeln('shouldn''t happen');
halt(2);
end;
function GetManRec: ManRec;
begin
result.x := 1;
end;
procedure Use(const mr: ManRec);
begin
end;
procedure Main;
var
mr: ManRec;
begin
{$ifdef doublefree}
GetManRec; // imperfect, double Finalize()
{$else}
mr := GetManRec; // ok
Use(GetManRec); // ok as well
{$endif}
end;
begin
Main;
writeln('InitCount = ', InitCount, ' (should ideally be 0).');
if InitCount <> 0 then
halt(1);
end.