summaryrefslogtreecommitdiff
path: root/vala
diff options
context:
space:
mode:
authorJürg Billeter <j@bitron.ch>2008-11-29 12:47:52 +0000
committerJürg Billeter <juergbi@src.gnome.org>2008-11-29 12:47:52 +0000
commit44a1c2f3196261abbc0930f84df21fc877afd266 (patch)
tree1db18353d58ac91f214ba24e9e22c5fbf1c0da35 /vala
parent9c5443a1041e28145f8b68c0c58d8d73e5857fce (diff)
downloadvala-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
Diffstat (limited to 'vala')
-rw-r--r--vala/valaflowanalyzer.vala47
1 files changed, 39 insertions, 8 deletions
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);