mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 23:28:13 +02:00
Merged revision(s) 48972, 49057 from trunk:
+ tx64tryfinallynode.dogetcopy properly implemented, resolves #37305 ........ * patch by Do-wan Kim: fix loop unrolling for try .. finally blocks in win32, similiar to r48972 for win64 ........ git-svn-id: branches/fixes_3_2@49316 -
This commit is contained in:
parent
ea640967ee
commit
4b7f92a367
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -17803,6 +17803,8 @@ tests/webtbs/tw3719.pp svneol=native#text/plain
|
||||
tests/webtbs/tw3721.pp svneol=native#text/plain
|
||||
tests/webtbs/tw37218.pp svneol=native#text/pascal
|
||||
tests/webtbs/tw37228.pp svneol=native#text/plain
|
||||
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/tw37355.pp svneol=native#text/pascal
|
||||
|
@ -46,6 +46,7 @@ interface
|
||||
constructor create(l,r:TNode);override;
|
||||
constructor create_implicit(l,r:TNode);override;
|
||||
function pass_1: tnode;override;
|
||||
function dogetcopy : tnode;override;
|
||||
function simplify(forinline: boolean): tnode;override;
|
||||
procedure pass_generate_code;override;
|
||||
end;
|
||||
@ -59,7 +60,7 @@ implementation
|
||||
cgbase,cgobj,cgcpu,cgutils,tgobj,
|
||||
cpubase,htypechk,
|
||||
parabase,paramgr,pass_1,pass_2,ncgutil,cga,
|
||||
aasmbase,aasmtai,aasmdata,aasmcpu,procinfo,cpupi;
|
||||
aasmbase,aasmtai,aasmdata,aasmcpu,procinfo,cpupi,procdefutil;
|
||||
|
||||
var
|
||||
endexceptlabel: tasmlabel;
|
||||
@ -215,6 +216,30 @@ function ti386tryfinallynode.pass_1: tnode;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ti386tryfinallynode.dogetcopy: tnode;
|
||||
var
|
||||
n: ti386tryfinallynode;
|
||||
begin
|
||||
n:=ti386tryfinallynode(inherited dogetcopy);
|
||||
if target_info.system=system_i386_win32 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 ti386tryfinallynode.simplify(forinline: boolean): tnode;
|
||||
begin
|
||||
@ -222,7 +247,8 @@ function ti386tryfinallynode.simplify(forinline: boolean): tnode;
|
||||
if (target_info.system<>system_i386_win32) then
|
||||
exit;
|
||||
|
||||
if (result=nil) and assigned(finalizepi) then
|
||||
{ actually, this is not really the right place to do a node transformation like this }
|
||||
if (result=nil) and assigned(finalizepi) and (not(assigned(finalizepi.code))) then
|
||||
begin
|
||||
finalizepi.code:=right;
|
||||
foreachnodestatic(right,@copy_parasize,finalizepi);
|
||||
|
@ -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;
|
||||
@ -169,6 +171,7 @@ constructor tx64tryfinallynode.create(l, r: TNode);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
constructor tx64tryfinallynode.create_implicit(l, r: TNode);
|
||||
begin
|
||||
inherited create_implicit(l, r);
|
||||
@ -185,6 +188,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);
|
||||
@ -192,22 +222,27 @@ 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;
|
||||
{ don't leave dangling pointer }
|
||||
tcgprocinfo(current_procinfo).final_asmnode:=nil;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure emit_nop;
|
||||
var
|
||||
dummy: TAsmLabel;
|
||||
@ -219,6 +254,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
13
tests/webtbs/tw37305a.pp
Normal 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
12
tests/webtbs/tw37305b.pp
Normal 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.
|
Loading…
Reference in New Issue
Block a user