fix memory management of parameters with ownership transfer, fixes bug
authorJuerg Billeter <j@bitron.ch>
Fri, 15 Feb 2008 11:26:50 +0000 (11:26 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Fri, 15 Feb 2008 11:26:50 +0000 (11:26 +0000)
2008-02-15  Juerg Billeter  <j@bitron.ch>

* 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
gobject/valaccodegenerator.vala
vala/valamethod.vala
vala/valasemanticanalyzer.vala

index 328c173..e87190e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-02-15  Jürg Billeter  <j@bitron.ch>
+
+       * 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  <j@bitron.ch>
 
        * vala/valainterfacewriter.vala: avoid testing floating point
index b2d49c1..8b2f37f 100644 (file)
@@ -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);
                
index d3c9f85..7585576 100644 (file)
@@ -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<Expression> preconditions = new ArrayList<Expression> ();
        private Gee.List<Expression> postconditions = new ArrayList<Expression> ();
        private DataType _return_type;
+       private Block _body;
 
        /**
         * Creates a new method.
index 449b62e..5f02c8f 100644 (file)
@@ -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