From fca101bfee9c47257aea44bd031a888bd0872cbd Mon Sep 17 00:00:00 2001 From: Juerg Billeter Date: Fri, 15 Feb 2008 11:26:50 +0000 Subject: [PATCH] fix memory management of parameters with ownership transfer, fixes bug 2008-02-15 Juerg Billeter * vala/valamethod.vala, vala/valasemanticanalyzer.vala, gobject/valaccodegenerator.vala: fix memory management of parameters with ownership transfer, fixes bug 511642 svn path=/trunk/; revision=1010 --- ChangeLog | 6 ++++++ gobject/valaccodegenerator.vala | 42 ++++++++++++++++++++++++++++++++++++++++- vala/valamethod.vala | 11 ++++++++++- vala/valasemanticanalyzer.vala | 6 ++++-- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 328c173..e87190e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-02-15 Jürg Billeter + + * vala/valamethod.vala, vala/valasemanticanalyzer.vala, + gobject/valaccodegenerator.vala: fix memory management of + parameters with ownership transfer, fixes bug 511642 + 2008-02-14 Jürg Billeter * vala/valainterfacewriter.vala: avoid testing floating point diff --git a/gobject/valaccodegenerator.vala b/gobject/valaccodegenerator.vala index b2d49c1..8b2f37f 100644 --- a/gobject/valaccodegenerator.vala +++ b/gobject/valaccodegenerator.vala @@ -873,6 +873,17 @@ public class Vala.CCodeGenerator : CodeGenerator { } } + if (b.parent_symbol is Method) { + var m = (Method) b.parent_symbol; + foreach (FormalParameter param in m.get_parameters ()) { + if (param.type_reference.data_type != null && param.type_reference.data_type.is_reference_type () && param.type_reference.takes_ownership) { + var ma = new MemberAccess.simple (param.name); + ma.symbol_reference = param; + cblock.add_statement (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier (get_variable_cname (param.name)), param.type_reference, ma))); + } + } + } + b.ccodenode = cblock; current_symbol = current_symbol.parent_symbol; @@ -1876,6 +1887,18 @@ public class Vala.CCodeGenerator : CodeGenerator { if (sym.parent_symbol is Block) { append_local_free (sym.parent_symbol, cfrag, stop_at_loop); + } 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 (param.type_reference.data_type != null && param.type_reference.data_type.is_reference_type () && param.type_reference.takes_ownership) { + var ma = new MemberAccess.simple (param.name); + ma.symbol_reference = param; + cfrag.append (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier (get_variable_cname (param.name)), param.type_reference, ma))); + } } } @@ -1889,7 +1912,7 @@ public class Vala.CCodeGenerator : CodeGenerator { } private bool append_local_free_expr (Symbol sym, CCodeCommaExpression ccomma, bool stop_at_loop) { - var found = false; + bool found = false; var b = (Block) sym; @@ -1905,11 +1928,28 @@ public class Vala.CCodeGenerator : CodeGenerator { if (sym.parent_symbol is Block) { found = append_local_free_expr (sym.parent_symbol, ccomma, stop_at_loop) || found; + } else if (sym.parent_symbol is Method) { + found = append_param_free_expr ((Method) sym.parent_symbol, ccomma) || found; } return found; } + private bool append_param_free_expr (Method m, CCodeCommaExpression ccomma) { + bool found = false; + + foreach (FormalParameter param in m.get_parameters ()) { + if (param.type_reference.data_type != null && param.type_reference.data_type.is_reference_type () && param.type_reference.takes_ownership) { + found = true; + var ma = new MemberAccess.simple (param.name); + ma.symbol_reference = param; + ccomma.append_expression (get_unref_expression (new CCodeIdentifier (get_variable_cname (param.name)), param.type_reference, ma)); + } + } + + return found; + } + private void create_local_free_expr (Expression expr) { var return_expr_decl = get_temp_variable_declarator (expr.static_type, true, expr); diff --git a/vala/valamethod.vala b/vala/valamethod.vala index d3c9f85..7585576 100644 --- a/vala/valamethod.vala +++ b/vala/valamethod.vala @@ -41,7 +41,15 @@ public class Vala.Method : Member { } } - public Block body { get; set; } + public Block body { + get { return _body; } + set { + _body = value; + if (_body != null) { + _body.owner = scope; + } + } + } public BasicBlock entry_block { get; set; } @@ -193,6 +201,7 @@ public class Vala.Method : Member { private Gee.List preconditions = new ArrayList (); private Gee.List postconditions = new ArrayList (); private DataType _return_type; + private Block _body; /** * Creates a new method. diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 449b62e..5f02c8f 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -1284,7 +1284,9 @@ public class Vala.SemanticAnalyzer : CodeVisitor { return type; } else if (sym is FormalParameter) { var p = (FormalParameter) sym; - return p.type_reference; + var type = p.type_reference.copy (); + type.transfers_ownership = false; + return type; } else if (sym is DataType) { return (DataType) sym; } else if (sym is VariableDeclarator) { @@ -1703,7 +1705,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { Report.error (expr.source_reference, "Argument %d: Cannot convert from `%s' to `%s'".printf (i + 1, arg.static_type.to_string (), param.type_reference.to_string ())); return false; } else if (context.is_non_null_enabled ()) { - Report.warning (expr.source_reference, "Argument %d: Argument may not be null".printf (i + 1, arg.static_type.to_string (), param.type_reference.to_string ())); + Report.warning (expr.source_reference, "Argument %d: Argument may not be null".printf (i + 1)); } } else { // 0 => null, 1 => in, 2 => ref, 3 => out -- 2.7.4