diff --git a/.gitattributes b/.gitattributes index 559d05925b..28acc0df82 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/compiler/x86_64/nx64flw.pas b/compiler/x86_64/nx64flw.pas index f0ceb44b62..e2612e584d 100644 --- a/compiler/x86_64/nx64flw.pas +++ b/compiler/x86_64/nx64flw.pas @@ -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, diff --git a/tests/webtbs/tw37305a.pp b/tests/webtbs/tw37305a.pp new file mode 100644 index 0000000000..b07f0d4630 --- /dev/null +++ b/tests/webtbs/tw37305a.pp @@ -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. diff --git a/tests/webtbs/tw37305b.pp b/tests/webtbs/tw37305b.pp new file mode 100644 index 0000000000..dd39eb1769 --- /dev/null +++ b/tests/webtbs/tw37305b.pp @@ -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.