From: Jürg Billeter Date: Sun, 1 Jun 2008 13:10:39 +0000 (+0000) Subject: Fix memory management when using owned variables as argument for unowned X-Git-Tag: VALA_0_3_3~31 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ad877ad064d84c0f352a509ba56dd220f03ee360;p=platform%2Fupstream%2Fvala.git Fix memory management when using owned variables as argument for unowned 2008-06-01 Jürg Billeter * gobject/valaccodeinvocationexpressionbinding.vala: Fix memory management when using owned variables as argument for unowned reference and output parameters * tests/classes-methods.vala: Test owned and unowned variables as argument for reference and output parameters svn path=/trunk/; revision=1527 --- diff --git a/ChangeLog b/ChangeLog index d01abb1..13c4f16 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ 2008-06-01 Jürg Billeter + * gobject/valaccodeinvocationexpressionbinding.vala: + + Fix memory management when using owned variables as argument + for unowned reference and output parameters + + * tests/classes-methods.vala: + + Test owned and unowned variables as argument for reference and + output parameters + +2008-06-01 Jürg Billeter + * vala/valasemanticanalyzer.vala: Report error when trying to use unowned variables as argument diff --git a/gobject/valaccodeinvocationexpressionbinding.vala b/gobject/valaccodeinvocationexpressionbinding.vala index 189ca74..1d52c63 100644 --- a/gobject/valaccodeinvocationexpressionbinding.vala +++ b/gobject/valaccodeinvocationexpressionbinding.vala @@ -222,19 +222,27 @@ public class Vala.CCodeInvocationExpressionBinding : CCodeExpressionBinding { ccall_expr = ccomma; } - // unref old value for non-null non-weak out arguments + // unref old value for non-null non-weak ref/out arguments // disabled for arrays for now as that requires special handling - if (param.direction == ParameterDirection.OUT && codegen.requires_destroy (param.parameter_type) - && !(arg.value_type is NullType || param.parameter_type is ArrayType)) { + // (ret_tmp = call (&tmp), var1 = (assign_tmp = dup (tmp), free (var1), assign_tmp), ret_tmp) + if (param.direction != ParameterDirection.IN && codegen.requires_destroy (arg.value_type) + && (param.direction == ParameterDirection.OUT || !param.parameter_type.value_owned) + && !(param.parameter_type is ArrayType)) { var unary = (UnaryExpression) arg; - // (ret_tmp = call (&tmp), free (var1), var1 = tmp, ret_tmp) var ccomma = new CCodeCommaExpression (); - var temp_var = codegen.get_temp_variable (unary.inner.value_type); + var temp_var = codegen.get_temp_variable (param.parameter_type, param.parameter_type.value_owned); codegen.temp_vars.insert (0, temp_var); cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_var.name)); + if (param.direction == ParameterDirection.REF) { + var crefcomma = new CCodeCommaExpression (); + crefcomma.append_expression (new CCodeAssignment (new CCodeIdentifier (temp_var.name), (CCodeExpression) unary.inner.ccodenode)); + crefcomma.append_expression (cexpr); + cexpr = crefcomma; + } + // call function LocalVariable ret_temp_var; if (m.return_type is VoidType) { @@ -245,11 +253,20 @@ public class Vala.CCodeInvocationExpressionBinding : CCodeExpressionBinding { ccomma.append_expression (new CCodeAssignment (new CCodeIdentifier (ret_temp_var.name), ccall_expr)); } + var cassign_comma = new CCodeCommaExpression (); + + var assign_temp_var = codegen.get_temp_variable (unary.inner.value_type, unary.inner.value_type.value_owned); + codegen.temp_vars.insert (0, assign_temp_var); + + cassign_comma.append_expression (new CCodeAssignment (new CCodeIdentifier (assign_temp_var.name), codegen.transform_expression (new CCodeIdentifier (temp_var.name), param.parameter_type, unary.inner.value_type, arg))); + // unref old value - ccomma.append_expression (codegen.get_unref_expression ((CCodeExpression) unary.inner.ccodenode, arg.value_type, arg)); + cassign_comma.append_expression (codegen.get_unref_expression ((CCodeExpression) unary.inner.ccodenode, arg.value_type, arg)); + + cassign_comma.append_expression (new CCodeIdentifier (assign_temp_var.name)); // assign new value - ccomma.append_expression (new CCodeAssignment ((CCodeExpression) unary.inner.ccodenode, new CCodeIdentifier (temp_var.name))); + ccomma.append_expression (new CCodeAssignment ((CCodeExpression) unary.inner.ccodenode, cassign_comma)); // return value if (!(m.return_type is VoidType)) { diff --git a/tests/classes-methods.vala b/tests/classes-methods.vala index a0d6483..e3854d0 100644 --- a/tests/classes-methods.vala +++ b/tests/classes-methods.vala @@ -60,6 +60,27 @@ class Maman.SubBar : Bar { BaseAccess.test (); + string str, str2; + weak string weak_str; + + test_out (out str); + assert (str == "hello"); + + test_out_weak (out weak_str); + assert (weak_str == "hello"); + + test_out_weak (out str2); + assert (str == "hello"); + + test_ref (ref str); + assert (str == "world"); + + test_ref_weak (ref weak_str); + assert (str == "world"); + + test_ref_weak (ref str2); + assert (str == "world"); + return 0; } } @@ -144,3 +165,21 @@ namespace Maman.BaseAccess { } } +void test_out (out string bar) { + bar = "hello"; +} + +void test_out_weak (out weak string bar) { + bar = "hello"; +} + +void test_ref (ref string bar) { + assert (bar == "hello"); + bar = "world"; +} + +void test_ref_weak (ref weak string bar) { + assert (bar == "hello"); + bar = "world"; +} +