]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Don't append unreachable clean-up section of Block
authorRico Tzschichholz <ricotz@ubuntu.com>
Mon, 17 Aug 2020 14:37:59 +0000 (16:37 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Sat, 5 Sep 2020 14:42:41 +0000 (16:42 +0200)
Found by -Werror=unreachable-code

Improvements for https://gitlab.gnome.org/GNOME/vala/issues/838

Fixes https://gitlab.gnome.org/GNOME/vala/issues/169

codegen/valaccodebasemodule.vala

index 89a04130ebdcaca17e8ced81b59712aef39e1b7f..f9b71170d15fe2fc00f8af31cbd9a131ba1b82bd 100644 (file)
@@ -2310,52 +2310,58 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        cfile.add_function (unref_fun);
                }
 
+               bool reachable_exit_block = true;
                foreach (Statement stmt in b.get_statements ()) {
+                       if (stmt is ReturnStatement) {
+                               reachable_exit_block = false;
+                       }
                        push_line (stmt.source_reference);
                        stmt.emit (this);
                        pop_line ();
                }
 
-               if (b.parent_symbol is Method) {
-                       unowned Method m = (Method) b.parent_symbol;
-                       // check postconditions
-                       foreach (var postcondition in m.get_postconditions ()) {
-                               create_postcondition_statement (postcondition);
+               if (reachable_exit_block) {
+                       if (b.parent_symbol is Method) {
+                               unowned Method m = (Method) b.parent_symbol;
+                               // check postconditions
+                               foreach (var postcondition in m.get_postconditions ()) {
+                                       create_postcondition_statement (postcondition);
+                               }
                        }
-               }
 
-               // free in reverse order
-               for (int i = local_vars.size - 1; i >= 0; i--) {
-                       var local = local_vars[i];
-                       local.active = false;
-                       if (!local.unreachable && !local.captured && requires_destroy (local.variable_type)) {
-                               ccode.add_expression (destroy_local (local));
+                       // free in reverse order
+                       for (int i = local_vars.size - 1; i >= 0; i--) {
+                               var local = local_vars[i];
+                               local.active = false;
+                               if (!local.unreachable && !local.captured && requires_destroy (local.variable_type)) {
+                                       ccode.add_expression (destroy_local (local));
+                               }
                        }
-               }
 
-               if (b.parent_symbol is Method) {
-                       var m = (Method) b.parent_symbol;
-                       foreach (Parameter param in m.get_parameters ()) {
-                               if (!param.captured && !param.ellipsis && requires_destroy (param.variable_type) && param.direction == ParameterDirection.IN) {
-                                       ccode.add_expression (destroy_parameter (param));
-                               } else if (param.direction == ParameterDirection.OUT && !m.coroutine) {
-                                       return_out_parameter (param);
+                       if (b.parent_symbol is Method) {
+                               var m = (Method) b.parent_symbol;
+                               foreach (Parameter param in m.get_parameters ()) {
+                                       if (!param.captured && !param.ellipsis && requires_destroy (param.variable_type) && param.direction == ParameterDirection.IN) {
+                                               ccode.add_expression (destroy_parameter (param));
+                                       } else if (param.direction == ParameterDirection.OUT && !m.coroutine) {
+                                               return_out_parameter (param);
+                                       }
+                               }
+                       } else if (b.parent_symbol is PropertyAccessor) {
+                               var acc = (PropertyAccessor) b.parent_symbol;
+                               if (acc.value_parameter != null && !acc.value_parameter.captured && requires_destroy (acc.value_parameter.variable_type)) {
+                                       ccode.add_expression (destroy_parameter (acc.value_parameter));
                                }
                        }
-               } else if (b.parent_symbol is PropertyAccessor) {
-                       var acc = (PropertyAccessor) b.parent_symbol;
-                       if (acc.value_parameter != null && !acc.value_parameter.captured && requires_destroy (acc.value_parameter.variable_type)) {
-                               ccode.add_expression (destroy_parameter (acc.value_parameter));
-                       }
-               }
 
-               if (b.captured) {
-                       int block_id = get_block_id (b);
+                       if (b.captured) {
+                               int block_id = get_block_id (b);
 
-                       var data_unref = new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_unref".printf (block_id)));
-                       data_unref.add_argument (get_variable_cexpression ("_data%d_".printf (block_id)));
-                       ccode.add_expression (data_unref);
-                       ccode.add_assignment (get_variable_cexpression ("_data%d_".printf (block_id)), new CCodeConstant ("NULL"));
+                               var data_unref = new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_unref".printf (block_id)));
+                               data_unref.add_argument (get_variable_cexpression ("_data%d_".printf (block_id)));
+                               ccode.add_expression (data_unref);
+                               ccode.add_assignment (get_variable_cexpression ("_data%d_".printf (block_id)), new CCodeConstant ("NULL"));
+                       }
                }
 
                if (b.parent_node is Block || b.parent_node is SwitchStatement || b.parent_node is TryStatement) {