Browse Source

* correctly handle inlined exits in dfa, resolves #38259

git-svn-id: trunk@47894 -
florian 4 years ago
parent
commit
edfbf2ce30
4 changed files with 41 additions and 5 deletions
  1. 1 0
      .gitattributes
  2. 15 3
      compiler/optdfa.pas
  3. 8 2
      compiler/optutils.pas
  4. 17 0
      tests/webtbs/tw38259.pp

+ 1 - 0
.gitattributes

@@ -18619,6 +18619,7 @@ tests/webtbs/tw38202.pp svneol=native#text/pascal
 tests/webtbs/tw38225.pp svneol=native#text/pascal
 tests/webtbs/tw38225.pp svneol=native#text/pascal
 tests/webtbs/tw38238.pp svneol=native#text/pascal
 tests/webtbs/tw38238.pp svneol=native#text/pascal
 tests/webtbs/tw38249.pp svneol=native#text/pascal
 tests/webtbs/tw38249.pp svneol=native#text/pascal
+tests/webtbs/tw38259.pp svneol=native#text/pascal
 tests/webtbs/tw3827.pp svneol=native#text/plain
 tests/webtbs/tw3827.pp svneol=native#text/plain
 tests/webtbs/tw3829.pp svneol=native#text/plain
 tests/webtbs/tw3829.pp svneol=native#text/plain
 tests/webtbs/tw3833.pp svneol=native#text/plain
 tests/webtbs/tw3833.pp svneol=native#text/plain

+ 15 - 3
compiler/optdfa.pas

@@ -508,20 +508,32 @@ unit optdfa;
 
 
             exitn:
             exitn:
               begin
               begin
-                if not(is_void(current_procinfo.procdef.returndef)) then
+                { in case of inlining, an exit node can have a successor, in this case, we do not have to
+                  use the faked resultnode }
+                if assigned(node.successor) then
+                  begin
+                    l:=node.optinfo^.life;
+                    DFASetIncludeSet(l,node.successor.optinfo^.life);
+                    UpdateLifeInfo(node,l);
+                  end
+                else if assigned(resultnode) and (resultnode.nodetype<>nothingn) then
                   begin
                   begin
                     if not(assigned(node.optinfo^.def)) and
                     if not(assigned(node.optinfo^.def)) and
                        not(assigned(node.optinfo^.use)) then
                        not(assigned(node.optinfo^.use)) then
                       begin
                       begin
                         if assigned(texitnode(node).left) then
                         if assigned(texitnode(node).left) then
                           begin
                           begin
-                            node.optinfo^.def:=resultnode.optinfo^.def;
+{                           this should never happen as
+                            texitnode.pass_typecheck converts the left node into a separate node already
+
+                             node.optinfo^.def:=resultnode.optinfo^.def;
 
 
                             dfainfo.use:[email protected]^.use;
                             dfainfo.use:[email protected]^.use;
                             dfainfo.def:[email protected]^.def;
                             dfainfo.def:[email protected]^.def;
                             dfainfo.map:=map;
                             dfainfo.map:=map;
                             foreachnodestatic(pm_postprocess,texitnode(node).left,@AddDefUse,@dfainfo);
                             foreachnodestatic(pm_postprocess,texitnode(node).left,@AddDefUse,@dfainfo);
-                            calclife(node);
+                            calclife(node); }
+                            Internalerror(2020122901);
                           end
                           end
                         else
                         else
                           begin
                           begin

+ 8 - 2
compiler/optutils.pas

@@ -163,11 +163,12 @@ unit optutils;
       var
       var
         Continuestack : TFPList;
         Continuestack : TFPList;
         Breakstack : TFPList;
         Breakstack : TFPList;
+        Exitsuccessor: TNode;
       { sets the successor nodes of a node tree block
       { sets the successor nodes of a node tree block
         returns the first node of the tree if it's a controll flow node }
         returns the first node of the tree if it's a controll flow node }
       function DoSet(p : tnode;succ : tnode) : tnode;
       function DoSet(p : tnode;succ : tnode) : tnode;
         var
         var
-          hp1,hp2 : tnode;
+          hp1,hp2, oldexitsuccessor: tnode;
           i : longint;
           i : longint;
         begin
         begin
           result:=nil;
           result:=nil;
@@ -203,11 +204,15 @@ unit optutils;
             blockn:
             blockn:
               begin
               begin
                 result:=p;
                 result:=p;
+                oldexitsuccessor:=Exitsuccessor;
+                if nf_block_with_exit in p.flags then
+                  Exitsuccessor:=succ;
                 DoSet(tblocknode(p).statements,succ);
                 DoSet(tblocknode(p).statements,succ);
                 if assigned(tblocknode(p).statements) then
                 if assigned(tblocknode(p).statements) then
                   p.successor:=tblocknode(p).statements
                   p.successor:=tblocknode(p).statements
                 else
                 else
                   p.successor:=succ;
                   p.successor:=succ;
+                Exitsuccessor:=oldexitsuccessor;
               end;
               end;
             forn:
             forn:
               begin
               begin
@@ -288,7 +293,7 @@ unit optutils;
             exitn:
             exitn:
               begin
               begin
                 result:=p;
                 result:=p;
-                p.successor:=nil;
+                p.successor:=Exitsuccessor;
               end;
               end;
             casen:
             casen:
               begin
               begin
@@ -337,6 +342,7 @@ unit optutils;
       begin
       begin
         Breakstack:=TFPList.Create;
         Breakstack:=TFPList.Create;
         Continuestack:=TFPList.Create;
         Continuestack:=TFPList.Create;
+        Exitsuccessor:=nil;
         DoSet(p,last);
         DoSet(p,last);
         Continuestack.Free;
         Continuestack.Free;
         Breakstack.Free;
         Breakstack.Free;

+ 17 - 0
tests/webtbs/tw38259.pp

@@ -0,0 +1,17 @@
+{ %OPT=-O3 -Sew -vw }
+{$mode objfpc}
+{$inline on}
+
+procedure test; inline;
+begin
+  exit;
+end;
+
+function f: longint;
+begin
+  test; // tt.pp(11,3) Warning: Function result variable does not seem to be initialized
+  result:=4;
+end;
+
+begin
+end.