Browse Source

* patch by J. Gareth Moreton: propagate exit use in nested try...except statements,
resolves #35841

git-svn-id: trunk@47066 -

florian 4 years ago
parent
commit
73c041a854
3 changed files with 37 additions and 0 deletions
  1. 1 0
      .gitattributes
  2. 18 0
      compiler/x86_64/nx64flw.pas
  3. 18 0
      tests/webtbs/tw35841.pp

+ 1 - 0
.gitattributes

@@ -18367,6 +18367,7 @@ tests/webtbs/tw3578.pp svneol=native#text/plain
 tests/webtbs/tw3579.pp svneol=native#text/plain
 tests/webtbs/tw3579.pp svneol=native#text/plain
 tests/webtbs/tw35820.pp svneol=native#text/pascal
 tests/webtbs/tw35820.pp svneol=native#text/pascal
 tests/webtbs/tw3583.pp svneol=native#text/plain
 tests/webtbs/tw3583.pp svneol=native#text/plain
+tests/webtbs/tw35841.pp svneol=native#text/pascal
 tests/webtbs/tw35862.pp svneol=native#text/pascal
 tests/webtbs/tw35862.pp svneol=native#text/pascal
 tests/webtbs/tw35878.pp svneol=native#text/plain
 tests/webtbs/tw35878.pp svneol=native#text/plain
 tests/webtbs/tw35878a.pp svneol=native#text/plain
 tests/webtbs/tw35878a.pp svneol=native#text/plain

+ 18 - 0
compiler/x86_64/nx64flw.pas

@@ -321,6 +321,12 @@ procedure tx64tryfinallynode.pass_generate_code;
         cg.a_label(current_asmdata.CurrAsmList,endtrylabel);
         cg.a_label(current_asmdata.CurrAsmList,endtrylabel);
       end;
       end;
 
 
+    { i32913 - if the try..finally block is also inside a try..finally or
+      try..except block, make a note of any Exit calls so all necessary labels
+      are generated. [Kit] }
+    if (fc_exit in flowcontrol) and (fc_inflowcontrol in oldflowcontrol) then
+      Include(oldflowcontrol, fc_exit);
+
     flowcontrol:=[fc_inflowcontrol];
     flowcontrol:=[fc_inflowcontrol];
     { generate finally code as a separate procedure }
     { generate finally code as a separate procedure }
     if not implicitframe then
     if not implicitframe then
@@ -431,6 +437,12 @@ procedure tx64tryexceptnode.pass_generate_code;
         current_procinfo.CurrBreakLabel:=breakexceptlabel;
         current_procinfo.CurrBreakLabel:=breakexceptlabel;
       end;
       end;
 
 
+    { i32913 - if the try..finally block is also inside a try..finally or
+      try..except block, make a note of any Exit calls so all necessary labels
+      are generated. [Kit] }
+    if (fc_exit in flowcontrol) and (fc_inflowcontrol in oldflowcontrol) then
+      Include(oldflowcontrol, fc_exit);
+
     flowcontrol:=[fc_inflowcontrol];
     flowcontrol:=[fc_inflowcontrol];
     { on statements }
     { on statements }
     if assigned(right) then
     if assigned(right) then
@@ -521,6 +533,12 @@ errorexit:
     { restore all saved labels }
     { restore all saved labels }
     endexceptlabel:=oldendexceptlabel;
     endexceptlabel:=oldendexceptlabel;
 
 
+    { i32913 - if the try..finally block is also inside a try..finally or
+      try..except block, make a note of any Exit calls so all necessary labels
+      are generated. [Kit] }
+    if (fc_exit in flowcontrol) and (fc_inflowcontrol in oldflowcontrol) then
+      Include(oldflowcontrol, fc_exit);
+
     { restore the control flow labels }
     { restore the control flow labels }
     current_procinfo.CurrExitLabel:=oldCurrExitLabel;
     current_procinfo.CurrExitLabel:=oldCurrExitLabel;
     if assigned(oldBreakLabel) then
     if assigned(oldBreakLabel) then

+ 18 - 0
tests/webtbs/tw35841.pp

@@ -0,0 +1,18 @@
+{ %norun }
+{$mode objfpc}
+procedure p;
+  begin
+    try
+      writeln
+    except
+      try
+        writeln;
+        Exit;
+      finally
+        writeln;
+      end;
+    end;
+  end;
+
+begin
+end.