Browse Source

+ tx64tryfinallynode.dogetcopy properly implemented, resolves #37305

git-svn-id: trunk@48972 -
florian 4 years ago
parent
commit
2b47425f08
4 changed files with 73 additions and 10 deletions
  1. 2 0
      .gitattributes
  2. 46 10
      compiler/x86_64/nx64flw.pas
  3. 13 0
      tests/webtbs/tw37305a.pp
  4. 12 0
      tests/webtbs/tw37305b.pp

+ 2 - 0
.gitattributes

@@ -18647,6 +18647,8 @@ tests/webtbs/tw37261.pp svneol=native#text/pascal
 tests/webtbs/tw37272a.pp svneol=native#text/pascal
 tests/webtbs/tw37272a.pp svneol=native#text/pascal
 tests/webtbs/tw37286.pp svneol=native#text/pascal
 tests/webtbs/tw37286.pp svneol=native#text/pascal
 tests/webtbs/tw37301.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/tw37322.pp svneol=native#text/pascal
 tests/webtbs/tw37323.pp svneol=native#text/pascal
 tests/webtbs/tw37323.pp svneol=native#text/pascal
 tests/webtbs/tw37339.pp svneol=native#text/pascal
 tests/webtbs/tw37339.pp svneol=native#text/pascal

+ 46 - 10
compiler/x86_64/nx64flw.pas

@@ -45,6 +45,7 @@ interface
       finalizepi: tcgprocinfo;
       finalizepi: tcgprocinfo;
       constructor create(l,r:TNode);override;
       constructor create(l,r:TNode);override;
       constructor create_implicit(l,r:TNode);override;
       constructor create_implicit(l,r:TNode);override;
+      function dogetcopy : tnode;override;
       function simplify(forinline: boolean): tnode;override;
       function simplify(forinline: boolean): tnode;override;
       procedure pass_generate_code;override;
       procedure pass_generate_code;override;
     end;
     end;
@@ -58,7 +59,8 @@ implementation
     cgbase,cgobj,cgutils,tgobj,
     cgbase,cgobj,cgutils,tgobj,
     cpubase,htypechk,
     cpubase,htypechk,
     pass_1,pass_2,
     pass_1,pass_2,
-    aasmbase,aasmtai,aasmdata,aasmcpu,procinfo,cpupi;
+    aasmbase,aasmtai,aasmdata,aasmcpu,
+    procinfo,cpupi,procdefutil;
 
 
   var
   var
     endexceptlabel: tasmlabel;
     endexceptlabel: tasmlabel;
@@ -173,6 +175,7 @@ constructor tx64tryfinallynode.create(l, r: TNode);
       end;
       end;
   end;
   end;
 
 
+
 constructor tx64tryfinallynode.create_implicit(l, r: TNode);
 constructor tx64tryfinallynode.create_implicit(l, r: TNode);
   begin
   begin
     inherited create_implicit(l, r);
     inherited create_implicit(l, r);
@@ -189,6 +192,33 @@ constructor tx64tryfinallynode.create_implicit(l, r: TNode);
       end;
       end;
   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;
 function tx64tryfinallynode.simplify(forinline: boolean): tnode;
   begin
   begin
     result:=inherited simplify(forinline);
     result:=inherited simplify(forinline);
@@ -196,20 +226,25 @@ function tx64tryfinallynode.simplify(forinline: boolean): tnode;
       exit;
       exit;
     if (result=nil) then
     if (result=nil) then
       begin
       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
           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;
       end;
   end;
   end;
 
 
+
 procedure emit_nop;
 procedure emit_nop;
   var
   var
     dummy: TAsmLabel;
     dummy: TAsmLabel;
@@ -221,6 +256,7 @@ procedure emit_nop;
     current_asmdata.CurrAsmList.concat(Taicpu.op_none(A_NOP,S_NO));
     current_asmdata.CurrAsmList.concat(Taicpu.op_none(A_NOP,S_NO));
   end;
   end;
 
 
+
 procedure tx64tryfinallynode.pass_generate_code;
 procedure tx64tryfinallynode.pass_generate_code;
   var
   var
     trylabel,
     trylabel,

+ 13 - 0
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.

+ 12 - 0
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.