[vala/0.36] codegen: When freeing local variables don't stop at "switch" on "continue"



commit cc47f0d0127bca7c6c61c8e4513e36e80c58737c
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Fri May 17 08:56:12 2019 +0200

    codegen: When freeing local variables don't stop at "switch" on "continue"
    
    So distinguish between BreakStatement and ContinueStatement to make the
    correct decision in append_local_free().
    
    Fixes https://gitlab.gnome.org/GNOME/vala/issues/799

 codegen/valaccodebasemodule.vala            | 11 ++++++++---
 codegen/valaccodecontrolflowmodule.vala     |  4 ++--
 codegen/valagasyncmodule.vala               |  2 +-
 codegen/valagerrormodule.vala               |  8 ++++----
 tests/Makefile.am                           |  1 +
 tests/control-flow/for-switch-continue.vala | 24 ++++++++++++++++++++++++
 6 files changed, 40 insertions(+), 10 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 48d706e37..57ee13c65 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -3648,17 +3648,22 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                }
        }
 
-       public void append_local_free (Symbol sym, bool stop_at_loop = false, CodeNode? stop_at = null) {
+       public void append_local_free (Symbol sym, Statement? jump_stmt = null, CodeNode? stop_at = null) {
                var b = (Block) sym;
 
                append_scope_free (sym, stop_at);
 
-               if (stop_at_loop) {
+               if (jump_stmt is BreakStatement) {
                        if (b.parent_node is Loop ||
                            b.parent_node is ForeachStatement ||
                            b.parent_node is SwitchStatement) {
                                return;
                        }
+               } else if (jump_stmt is ContinueStatement) {
+                       if (b.parent_node is Loop ||
+                           b.parent_node is ForeachStatement) {
+                               return;
+                       }
                }
 
                if (stop_at != null && b.parent_node == stop_at) {
@@ -3666,7 +3671,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                }
 
                if (sym.parent_symbol is Block) {
-                       append_local_free (sym.parent_symbol, stop_at_loop, stop_at);
+                       append_local_free (sym.parent_symbol, jump_stmt, stop_at);
                } else if (sym.parent_symbol is Method) {
                        append_param_free ((Method) sym.parent_symbol);
                } else if (sym.parent_symbol is PropertyAccessor) {
diff --git a/codegen/valaccodecontrolflowmodule.vala b/codegen/valaccodecontrolflowmodule.vala
index 91268e7d1..a549f0621 100644
--- a/codegen/valaccodecontrolflowmodule.vala
+++ b/codegen/valaccodecontrolflowmodule.vala
@@ -345,13 +345,13 @@ public abstract class Vala.CCodeControlFlowModule : CCodeMethodModule {
        }
 
        public override void visit_break_statement (BreakStatement stmt) {
-               append_local_free (current_symbol, true);
+               append_local_free (current_symbol, stmt);
 
                ccode.add_break ();
        }
 
        public override void visit_continue_statement (ContinueStatement stmt) {
-               append_local_free (current_symbol, true);
+               append_local_free (current_symbol, stmt);
 
                ccode.add_continue ();
        }
diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala
index 6c706e8cf..214d86af2 100644
--- a/codegen/valagasyncmodule.vala
+++ b/codegen/valagasyncmodule.vala
@@ -866,7 +866,7 @@ public class Vala.GAsyncModule : GtkModule {
                set_error.add_argument (error_expr);
                ccode.add_expression (set_error);
 
-               append_local_free (current_symbol, false);
+               append_local_free (current_symbol);
 
                if (context.require_glib_version (2, 36)) {
                        // We already returned the error above, we must not return anything else here.
diff --git a/codegen/valagerrormodule.vala b/codegen/valagerrormodule.vala
index fc82fb46a..1c01cc940 100644
--- a/codegen/valagerrormodule.vala
+++ b/codegen/valagerrormodule.vala
@@ -100,7 +100,7 @@ public class Vala.GErrorModule : CCodeDelegateModule {
                ccode.add_expression (cpropagate);
 
                // free local variables
-               append_local_free (current_symbol, false);
+               append_local_free (current_symbol);
 
                if (current_method is CreationMethod && current_method.parent_symbol is Class) {
                        var cl = (Class) current_method.parent_symbol;
@@ -115,7 +115,7 @@ public class Vala.GErrorModule : CCodeDelegateModule {
 
        void uncaught_error_statement (CCodeExpression inner_error, bool unexpected = false) {
                // free local variables
-               append_local_free (current_symbol, false);
+               append_local_free (current_symbol);
 
                var ccritical = new CCodeFunctionCall (new CCodeIdentifier ("g_critical"));
                ccritical.add_argument (new CCodeConstant (unexpected ? "\"file %s: line %d: unexpected 
error: %s (%s, %d)\"" : "\"file %s: line %d: uncaught error: %s (%s, %d)\""));
@@ -183,9 +183,9 @@ public class Vala.GErrorModule : CCodeDelegateModule {
 
                        // free local variables
                        if (is_in_catch) {
-                               append_local_free (current_symbol, false, current_catch);
+                               append_local_free (current_symbol, null, current_catch);
                        } else {
-                               append_local_free (current_symbol, false, current_try);
+                               append_local_free (current_symbol, null, current_try);
                        }
 
                        var error_types = new ArrayList<DataType> ();
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7df354c66..332f4b589 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -133,6 +133,7 @@ TESTS = \
        control-flow/expressions-conditional.vala \
        control-flow/finally-return.test \
        control-flow/for.vala \
+       control-flow/for-switch-continue.vala \
        control-flow/foreach.vala \
        control-flow/missing-break.test \
        control-flow/missing-return.test \
diff --git a/tests/control-flow/for-switch-continue.vala b/tests/control-flow/for-switch-continue.vala
new file mode 100644
index 000000000..da58b1ad0
--- /dev/null
+++ b/tests/control-flow/for-switch-continue.vala
@@ -0,0 +1,24 @@
+bool success = false;
+
+class Foo : Object {
+       ~Foo () {
+               success = true;
+       }
+}
+
+void bar () {
+       assert (!success);
+       for (int i = 0; i < 1; i++) {
+               Foo? foo = null;
+               switch (i) {
+               case 0:
+                       foo = new Foo ();
+                       continue;
+               }
+       }
+       assert (success);
+}
+
+void main() {
+       bar ();
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]