Переглянути джерело

* DFA now takes case-completeness into account (mantis #35598)

git-svn-id: trunk@42091 -
Jonas Maebe 6 роки тому
батько
коміт
7e51c5e856
4 змінених файлів з 56 додано та 2 видалено
  1. 2 0
      .gitattributes
  2. 12 2
      compiler/optdfa.pas
  3. 20 0
      tests/test/opt/tdfa19.pp
  4. 22 0
      tests/test/opt/tdfa20.pp

+ 2 - 0
.gitattributes

@@ -12741,7 +12741,9 @@ tests/test/opt/tdfa15.pp svneol=native#text/pascal
 tests/test/opt/tdfa16.pp svneol=native#text/pascal
 tests/test/opt/tdfa17.pp svneol=native#text/pascal
 tests/test/opt/tdfa18.pp svneol=native#text/pascal
+tests/test/opt/tdfa19.pp svneol=native#text/plain
 tests/test/opt/tdfa2.pp svneol=native#text/pascal
+tests/test/opt/tdfa20.pp svneol=native#text/plain
 tests/test/opt/tdfa3.pp svneol=native#text/pascal
 tests/test/opt/tdfa4.pp svneol=native#text/pascal
 tests/test/opt/tdfa5.pp svneol=native#text/pascal

+ 12 - 2
compiler/optdfa.pas

@@ -53,7 +53,7 @@ unit optdfa;
   implementation
 
     uses
-      globtype,
+      globtype,constexp,
       verbose,
       symconst,symdef,symsym,
       defutil,
@@ -225,6 +225,7 @@ unit optdfa;
           dfainfo : tdfainfo;
           l : TDFASet;
           save: TDFASet;
+          lv, hv: TConstExprInt;
           i : longint;
           counteruse_after_loop : boolean;
         begin
@@ -485,7 +486,16 @@ unit optdfa;
                 if assigned(tcasenode(node).elseblock) then
                   DFASetIncludeSet(l,tcasenode(node).elseblock.optinfo^.life)
                 else if assigned(node.successor) then
-                  DFASetIncludeSet(l,node.successor.optinfo^.life);
+                  begin
+                    if is_ordinal(tcasenode(node).left.resultdef) then
+                      begin
+                        getrange(tcasenode(node).left.resultdef,lv,hv);
+                        if tcasenode(node).labelcoverage<(hv-lv) then
+                          DFASetIncludeSet(l,node.successor.optinfo^.life);
+                      end
+                    else
+                      DFASetIncludeSet(l,node.successor.optinfo^.life);
+                  end;
 
                 { add use info from the "case" expression }
                 DFASetIncludeSet(l,tcasenode(node).optinfo^.use);

+ 20 - 0
tests/test/opt/tdfa19.pp

@@ -0,0 +1,20 @@
+{ %OPT=-Oodfa -vw -Sew }
+{ %norun }
+
+{$mode objfpc}
+
+program project1;
+
+type
+  trange=0..5;
+
+function f(r: trange): longint;
+begin
+  case r of
+    0..5: result:=r;
+  end;
+end;
+
+begin
+  writeln(f(2));
+end.

+ 22 - 0
tests/test/opt/tdfa20.pp

@@ -0,0 +1,22 @@
+{ %OPT=-Oodfa -vw -Sew -vm6060 }
+{ %FAIL }
+
+{$mode objfpc}
+
+program project1;
+
+type
+  trange=0..5;
+
+function f(r: trange): longint;
+begin
+  { must give a warning about unset function result; warning about incomplete
+    case statement is suppressed with -vm6060 }
+  case r of
+    0..4: result:=r;
+  end;
+end;
+
+begin
+  writeln(f(2));
+end.