+ tx64tryfinallynode.dogetcopy properly implemented, resolves #37305

git-svn-id: trunk@48972 -
This commit is contained in:
florian 2021-03-14 21:23:05 +00:00
parent 76c61c3aac
commit 2b47425f08
4 changed files with 73 additions and 10 deletions

2
.gitattributes vendored
View File

@ -18647,6 +18647,8 @@ tests/webtbs/tw37261.pp svneol=native#text/pascal
tests/webtbs/tw37272a.pp svneol=native#text/pascal
tests/webtbs/tw37286.pp svneol=native#text/pascal
tests/webtbs/tw37301.pp svneol=native#text/pascal
tests/webtbs/tw37305a.pp svneol=native#text/pascal
tests/webtbs/tw37305b.pp svneol=native#text/pascal
tests/webtbs/tw37322.pp svneol=native#text/pascal
tests/webtbs/tw37323.pp svneol=native#text/pascal
tests/webtbs/tw37339.pp svneol=native#text/pascal

View File

@ -45,6 +45,7 @@ interface
finalizepi: tcgprocinfo;
constructor create(l,r:TNode);override;
constructor create_implicit(l,r:TNode);override;
function dogetcopy : tnode;override;
function simplify(forinline: boolean): tnode;override;
procedure pass_generate_code;override;
end;
@ -58,7 +59,8 @@ implementation
cgbase,cgobj,cgutils,tgobj,
cpubase,htypechk,
pass_1,pass_2,
aasmbase,aasmtai,aasmdata,aasmcpu,procinfo,cpupi;
aasmbase,aasmtai,aasmdata,aasmcpu,
procinfo,cpupi,procdefutil;
var
endexceptlabel: tasmlabel;
@ -173,6 +175,7 @@ constructor tx64tryfinallynode.create(l, r: TNode);
end;
end;
constructor tx64tryfinallynode.create_implicit(l, r: TNode);
begin
inherited create_implicit(l, r);
@ -189,6 +192,33 @@ constructor tx64tryfinallynode.create_implicit(l, r: TNode);
end;
end;
function tx64tryfinallynode.dogetcopy: tnode;
var
n: tx64tryfinallynode;
begin
n:=tx64tryfinallynode(inherited dogetcopy);
if target_info.system=system_x86_64_win64 then
begin
n.finalizepi:=tcgprocinfo(cprocinfo.create(finalizepi.parent));
n.finalizepi.force_nested;
n.finalizepi.procdef:=create_outline_procdef('$fin$',current_procinfo.procdef.struct,potype_exceptfilter,voidtype);
n.finalizepi.entrypos:=finalizepi.entrypos;
n.finalizepi.entryswitches:=finalizepi.entryswitches;
n.finalizepi.exitpos:=finalizepi.exitpos;
n.finalizepi.exitswitches:=finalizepi.exitswitches;
n.finalizepi.flags:=finalizepi.flags;
{ node already transformed? }
if assigned(finalizepi.code) then
begin
n.finalizepi.code:=finalizepi.code.getcopy;
n.right:=ccallnode.create(nil,tprocsym(n.finalizepi.procdef.procsym),nil,nil,[],nil);
end;
end;
result:=n;
end;
function tx64tryfinallynode.simplify(forinline: boolean): tnode;
begin
result:=inherited simplify(forinline);
@ -196,20 +226,25 @@ function tx64tryfinallynode.simplify(forinline: boolean): tnode;
exit;
if (result=nil) then
begin
finalizepi.code:=right;
foreachnodestatic(right,@copy_parasize,finalizepi);
right:=ccallnode.create(nil,tprocsym(finalizepi.procdef.procsym),nil,nil,[],nil);
firstpass(right);
{ For implicit frames, no actual code is available at this time,
it is added later in assembler form. So store the nested procinfo
for later use. }
if implicitframe then
{ actually, this is not really the right place to do a node transformation like this }
if not(assigned(finalizepi.code)) then
begin
current_procinfo.finalize_procinfo:=finalizepi;
finalizepi.code:=right;
foreachnodestatic(right,@copy_parasize,finalizepi);
right:=ccallnode.create(nil,tprocsym(finalizepi.procdef.procsym),nil,nil,[],nil);
firstpass(right);
{ For implicit frames, no actual code is available at this time,
it is added later in assembler form. So store the nested procinfo
for later use. }
if implicitframe then
begin
current_procinfo.finalize_procinfo:=finalizepi;
end;
end;
end;
end;
procedure emit_nop;
var
dummy: TAsmLabel;
@ -221,6 +256,7 @@ procedure emit_nop;
current_asmdata.CurrAsmList.concat(Taicpu.op_none(A_NOP,S_NO));
end;
procedure tx64tryfinallynode.pass_generate_code;
var
trylabel,

13
tests/webtbs/tw37305a.pp Normal file
View File

@ -0,0 +1,13 @@
{$mode objfpc}
var
i, j, c: Int32;
begin
c := 1;
for i := 0 to c do // SIGSEGV at runtime
try
j := i;
finally
if (j <> 0) then
j := 0;
end;
end.

12
tests/webtbs/tw37305b.pp Normal file
View File

@ -0,0 +1,12 @@
{$mode objfpc}
var
i, j: Int32;
begin
for i := 0 to 1 do // Error: Compilation raised exception internally
try
j := i;
finally
if (j <> 0) then
j := 0;
end;
end.