diff options
author | Jürg Billeter <j@bitron.ch> | 2008-11-29 12:47:52 +0000 |
---|---|---|
committer | Jürg Billeter <juergbi@src.gnome.org> | 2008-11-29 12:47:52 +0000 |
commit | 44a1c2f3196261abbc0930f84df21fc877afd266 (patch) | |
tree | 1db18353d58ac91f214ba24e9e22c5fbf1c0da35 | |
parent | 9c5443a1041e28145f8b68c0c58d8d73e5857fce (diff) | |
download | vala-44a1c2f3196261abbc0930f84df21fc877afd266.tar.gz |
Detect unreachable code in if and while statements
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
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | vala/valaflowanalyzer.vala | 47 |
2 files changed, 45 insertions, 8 deletions
@@ -1,5 +1,11 @@ 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: * vala/valablock.vala: * vala/valacodenode.vala: diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala index 12ea4b1d7..87bb257e6 100644 --- a/vala/valaflowanalyzer.vala +++ b/vala/valaflowanalyzer.vala @@ -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); |