From 44a1c2f3196261abbc0930f84df21fc877afd266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Billeter?= Date: Sat, 29 Nov 2008 12:47:52 +0000 Subject: Detect unreachable code in if and while statements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-11-29 Jürg Billeter * vala/valaflowanalyzer.vala: Detect unreachable code in if and while statements svn path=/trunk/; revision=2084 --- vala/valaflowanalyzer.vala | 47 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) (limited to '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); -- cgit v1.2.1