mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-13 10:09:23 +02:00
LLVM: fix double init/fini of local managed variables accessed from nested functions
resolves #40392
This commit is contained in:
parent
5676cf4c1a
commit
c96641f901
@ -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
64
tests/webtbs/tw40392.pp
Normal 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.
|
Loading…
Reference in New Issue
Block a user