]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Detect unreachable code in if and while statements
authorJürg Billeter <j@bitron.ch>
Sat, 29 Nov 2008 12:47:52 +0000 (12:47 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Sat, 29 Nov 2008 12:47:52 +0000 (12:47 +0000)
2008-11-29  Jürg Billeter  <j@bitron.ch>

* vala/valaflowanalyzer.vala:

Detect unreachable code in if and while statements

svn path=/trunk/; revision=2084

ChangeLog
vala/valaflowanalyzer.vala

index 33543fd2e10dc46ede8cab9dc4f273fa8fc42d0e..e820029b7c75d6001cda8d4046f8387a1579073a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-11-29  Jürg Billeter  <j@bitron.ch>
+
+       * vala/valaflowanalyzer.vala:
+
+       Detect unreachable code in if and while statements
+
 2008-11-29  Jürg Billeter  <j@bitron.ch>
 
        * vala/Makefile.am:
index 12ea4b1d70b240b74cdcc6326f6e034d8d328f00..87bb257e6d6425fddf50fbeaea686af4b65813e1 100644 (file)
@@ -541,6 +541,16 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                }
        }
 
+       bool always_true (Expression condition) {
+               var literal = condition as BooleanLiteral;
+               return (literal != null && literal.value);
+       }
+
+       bool always_false (Expression condition) {
+               var literal = condition as BooleanLiteral;
+               return (literal != null && !literal.value);
+       }
+
        public override void visit_if_statement (IfStatement stmt) {
                if (unreachable (stmt)) {
                        return;
@@ -553,14 +563,24 @@ public class Vala.FlowAnalyzer : CodeVisitor {
 
                // true block
                var last_block = current_block;
-               current_block = new BasicBlock ();
-               last_block.connect (current_block);
+               if (always_false (stmt.condition)) {
+                       current_block = null;
+                       unreachable_reported = false;
+               } else {
+                       current_block = new BasicBlock ();
+                       last_block.connect (current_block);
+               }
                stmt.true_statement.accept (this);
 
                // false block
                var last_true_block = current_block;
-               current_block = new BasicBlock ();
-               last_block.connect (current_block);
+               if (always_true (stmt.condition)) {
+                       current_block = null;
+                       unreachable_reported = false;
+               } else {
+                       current_block = new BasicBlock ();
+                       last_block.connect (current_block);
+               }
                if (stmt.false_statement != null) {
                        stmt.false_statement.accept (this);
                }
@@ -652,8 +672,13 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                handle_errors (stmt.condition);
 
                // loop block
-               current_block = new BasicBlock ();
-               condition_block.connect (current_block);
+               if (always_false (stmt.condition)) {
+                       current_block = null;
+                       unreachable_reported = false;
+               } else {
+                       current_block = new BasicBlock ();
+                       condition_block.connect (current_block);
+               }
                stmt.body.accept (this);
                // end of loop block reachable?
                if (current_block != null) {
@@ -661,8 +686,14 @@ public class Vala.FlowAnalyzer : CodeVisitor {
                }
 
                // after loop
-               condition_block.connect (after_loop_block);
-               current_block = after_loop_block;
+               // reachable?
+               if (always_true (stmt.condition) && after_loop_block.get_predecessors ().size == 0) {
+                       current_block = null;
+                       unreachable_reported = false;
+               } else {
+                       condition_block.connect (after_loop_block);
+                       current_block = after_loop_block;
+               }
 
                jump_stack.remove_at (jump_stack.size - 1);
                jump_stack.remove_at (jump_stack.size - 1);