]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Limit scope of locals freed on errors thrown from catch clauses
authorJürg Billeter <j@bitron.ch>
Thu, 13 Jan 2011 12:54:19 +0000 (13:54 +0100)
committerJürg Billeter <j@bitron.ch>
Thu, 13 Jan 2011 13:06:58 +0000 (14:06 +0100)
This fixes double unref of closures.

codegen/valaccodebasemodule.vala
codegen/valagerrormodule.vala

index c13a541af0e8f35814a3eb20b6ec9e34f4348de0..ba0cac133bca0a0a83b19efcbbeffbec2f9a589a 100644 (file)
@@ -31,6 +31,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                public Symbol? current_symbol;
                public ArrayList<Symbol> symbol_stack = new ArrayList<Symbol> ();
                public TryStatement current_try;
+               public CatchClause current_catch;
                public CCodeFunction ccode;
                public ArrayList<CCodeFunction> ccode_stack = new ArrayList<CCodeFunction> ();
                public ArrayList<LocalVariable> temp_ref_vars = new ArrayList<LocalVariable> ();
@@ -69,6 +70,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                set { emit_context.current_try = value; }
        }
 
+       public CatchClause current_catch {
+               get { return emit_context.current_catch; }
+               set { emit_context.current_catch = value; }
+       }
+
        public TypeSymbol? current_type_symbol {
                get {
                        var sym = current_symbol;
index 10352f7f3c2580a36bd4b14c927ae8c7f8a5a2a9..4d464ef984369b8a509c9e7dbab486e05c68fdbf 100644 (file)
@@ -179,7 +179,11 @@ public class Vala.GErrorModule : CCodeDelegateModule {
                        // surrounding try found
 
                        // free local variables
-                       append_local_free (current_symbol, false, current_try);
+                       if (is_in_catch) {
+                               append_local_free (current_symbol, false, current_catch);
+                       } else {
+                               append_local_free (current_symbol, false, current_try);
+                       }
 
                        var error_types = new ArrayList<DataType> ();
                        foreach (DataType node_error_type in node.get_error_types ()) {
@@ -295,6 +299,7 @@ public class Vala.GErrorModule : CCodeDelegateModule {
                var old_try = current_try;
                var old_try_id = current_try_id;
                var old_is_in_catch = is_in_catch;
+               var old_catch = current_catch;
                current_try = stmt;
                current_try_id = this_try_id;
                is_in_catch = true;
@@ -308,6 +313,7 @@ public class Vala.GErrorModule : CCodeDelegateModule {
                is_in_catch = true;
 
                foreach (CatchClause clause in stmt.get_catch_clauses ()) {
+                       current_catch = clause;
                        ccode.add_goto ("__finally%d".printf (this_try_id));
                        clause.emit (this);
                }
@@ -315,6 +321,7 @@ public class Vala.GErrorModule : CCodeDelegateModule {
                current_try = old_try;
                current_try_id = old_try_id;
                is_in_catch = old_is_in_catch;
+               current_catch = old_catch;
 
                ccode.add_label ("__finally%d".printf (this_try_id));
                if (stmt.finally_body != null) {