]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Fix unreachable catch clause detection
authorDidier 'Ptitjes <ptitjes@free.fr>
Fri, 8 May 2009 13:36:46 +0000 (15:36 +0200)
committerJürg Billeter <j@bitron.ch>
Sat, 6 Jun 2009 18:39:08 +0000 (20:39 +0200)
Fixes part of bug 579388.

Signed-off-by: Didier 'Ptitjes <ptitjes@free.fr>
vala/valaflowanalyzer.vala

index cf093e2db60b3711c0f0577fb66b5ee17e6a856b..320b8f0ed1dc98e9b7db9df4e3ba6446e4b8f5ab 100644 (file)
@@ -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) {