From: Didier 'Ptitjes Date: Fri, 8 May 2009 13:36:46 +0000 (+0200) Subject: Fix unreachable catch clause detection X-Git-Tag: 0.7.4~45 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a64c43198badcf3bbacaa9a9066f9e4d88166a8d;p=thirdparty%2Fvala.git Fix unreachable catch clause detection Fixes part of bug 579388. Signed-off-by: Didier 'Ptitjes --- diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala index cf093e2db..320b8f0ed 100644 --- a/vala/valaflowanalyzer.vala +++ b/vala/valaflowanalyzer.vala @@ -802,36 +802,45 @@ public class Vala.FlowAnalyzer : CodeVisitor { stmt.error = true; } - private void handle_errors (CodeNode node) { + private void handle_errors (CodeNode node, bool always_fail = false) { if (node.tree_can_fail) { var last_block = current_block; // exceptional control flow - for (int i = jump_stack.size - 1; i >= 0; i--) { - var jump_target = jump_stack[i]; - if (jump_target.is_return_target) { - current_block.connect (jump_target.basic_block); - current_block = null; - unreachable_reported = false; - break; - } else if (jump_target.is_error_target) { - // TODO check whether jump target catches node.error_type - current_block.connect (jump_target.basic_block); - if (jump_target.error_domain == null) { - // catch all clause + foreach (DataType error_data_type in node.get_error_types()) { + var error_type = error_data_type as ErrorType; + current_block = last_block; + unreachable_reported = true; + + for (int i = jump_stack.size - 1; i >= 0; i--) { + var jump_target = jump_stack[i]; + if (jump_target.is_return_target) { + current_block.connect (jump_target.basic_block); current_block = null; unreachable_reported = false; break; + } else if (jump_target.is_error_target) { + if (jump_target.error_domain == null + || (jump_target.error_domain == error_type.error_domain + && (jump_target.error_code == null + || jump_target.error_code == error_type.error_code))) { + current_block.connect (jump_target.basic_block); + current_block = null; + unreachable_reported = false; + break; + } + } else if (jump_target.is_finally_clause) { + current_block.connect (jump_target.basic_block); + current_block = jump_target.last_block; } - } else if (jump_target.is_finally_clause) { - current_block.connect (jump_target.basic_block); - current_block = jump_target.last_block; } } // normal control flow - current_block = new BasicBlock (); - last_block.connect (current_block); + if (!always_fail) { + current_block = new BasicBlock (); + last_block.connect (current_block); + } } } @@ -849,29 +858,7 @@ public class Vala.FlowAnalyzer : CodeVisitor { } current_block.add_node (stmt); - - for (int i = jump_stack.size - 1; i >= 0; i--) { - var jump_target = jump_stack[i]; - if (jump_target.is_return_target) { - current_block.connect (jump_target.basic_block); - current_block = null; - unreachable_reported = false; - return; - } else if (jump_target.is_error_target) { - // TODO check whether jump target catches stmt.error_type - current_block.connect (jump_target.basic_block); - if (jump_target.error_domain == null) { - current_block = null; - unreachable_reported = false; - return; - } - } else if (jump_target.is_finally_clause) { - current_block.connect (jump_target.basic_block); - current_block = jump_target.last_block; - } - } - - assert_not_reached (); + handle_errors (stmt, true); } public override void visit_try_statement (TryStatement stmt) { @@ -934,8 +921,9 @@ public class Vala.FlowAnalyzer : CodeVisitor { foreach (JumpTarget jump_target in catch_stack) { foreach (JumpTarget prev_target in catch_stack) { - if (prev_target == jump_target) + if (prev_target == jump_target) { break; + } if (prev_target.error_domain == jump_target.error_domain && prev_target.error_code == jump_target.error_code) { @@ -943,12 +931,6 @@ public class Vala.FlowAnalyzer : CodeVisitor { stmt.error = true; return; } - - if ((prev_target.error_domain == null) || - ((prev_target.error_domain != jump_target.error_domain) && - (prev_target.error_code == null))) { - Report.warning (jump_target.catch_clause.source_reference, "unreachable catch clause detected"); - } } if (jump_target.basic_block.get_predecessors ().size == 0) {