From: Jürg Billeter Date: Thu, 1 Jan 2009 19:03:49 +0000 (+0000) Subject: Fix memory leaks when handling errors, patch by Philip Van Hoof, fixes bug X-Git-Tag: VALA_0_5_4~40 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ff84253df22505a70bd3e32559f0f41945bf1bb3;p=thirdparty%2Fvala.git Fix memory leaks when handling errors, patch by Philip Van Hoof, fixes bug 2009-01-01 Jürg Billeter * gobject/valaccodebasemodule.vala: * gobject/valagerrormodule.vala: Fix memory leaks when handling errors, patch by Philip Van Hoof, fixes bug 557856 svn path=/trunk/; revision=2251 --- diff --git a/ChangeLog b/ChangeLog index 573068e15..2e2236b34 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-01-01 Jürg Billeter + + * gobject/valaccodebasemodule.vala: + * gobject/valagerrormodule.vala: + + Fix memory leaks when handling errors, patch by Philip Van Hoof, + fixes bug 557856 + 2008-12-30 Jürg Billeter * doc/valac.1: diff --git a/gobject/valaccodebasemodule.vala b/gobject/valaccodebasemodule.vala index 0b4549b16..c3378f7a3 100644 --- a/gobject/valaccodebasemodule.vala +++ b/gobject/valaccodebasemodule.vala @@ -2055,6 +2055,29 @@ public class Vala.CCodeBaseModule : CCodeModule { } } + public void append_error_free (Symbol sym, CCodeFragment cfrag, TryStatement current_try) { + var b = (Block) sym; + + var local_vars = b.get_local_variables (); + foreach (LocalVariable local in local_vars) { + if (local.active && !local.floating && requires_destroy (local.variable_type)) { + var ma = new MemberAccess.simple (local.name); + ma.symbol_reference = local; + cfrag.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma))); + } + } + + if (sym == current_try.body) { + return; + } + + if (sym.parent_symbol is Block) { + append_error_free (sym.parent_symbol, cfrag, current_try); + } else if (sym.parent_symbol is Method) { + append_param_free ((Method) sym.parent_symbol, cfrag); + } + } + private void append_param_free (Method m, CCodeFragment cfrag) { foreach (FormalParameter param in m.get_parameters ()) { if (requires_destroy (param.parameter_type) && param.direction == ParameterDirection.IN) { diff --git a/gobject/valagerrormodule.vala b/gobject/valagerrormodule.vala index c69b2da55..de527a998 100644 --- a/gobject/valagerrormodule.vala +++ b/gobject/valagerrormodule.vala @@ -105,6 +105,12 @@ public class Vala.GErrorModule : CCodeDelegateModule { // TODO might be the wrong one when using nested try statements var cerror_block = new CCodeBlock (); + + // free local variables + var free_frag = new CCodeFragment (); + append_error_free (current_symbol, free_frag, current_try); + cerror_block.add_statement (free_frag); + foreach (CatchClause clause in current_try.get_catch_clauses ()) { // go to catch clause if error domain matches var cgoto_stmt = new CCodeGotoStatement (clause.clabel_name); @@ -157,6 +163,12 @@ public class Vala.GErrorModule : CCodeDelegateModule { // unhandled error var cerror_block = new CCodeBlock (); + + // free local variables + var free_frag = new CCodeFragment (); + append_local_free (current_symbol, free_frag, false); + cerror_block.add_statement (free_frag); + // print critical message cerror_block.add_statement (cprint_frag);