diff options
author | Luca Bruno <lucabru@src.gnome.org> | 2011-03-17 18:29:28 +0100 |
---|---|---|
committer | Luca Bruno <lucabru@src.gnome.org> | 2011-04-30 11:32:53 +0200 |
commit | c3719316c34ef3e1e926dc68cd2ac8cfb9667722 (patch) | |
tree | 02afc47857b543a6d9daf620bcb30f00434cc648 | |
parent | 8eb920394daa627882de1f7eec43dac2f42fafe5 (diff) | |
download | vala-c3719316c34ef3e1e926dc68cd2ac8cfb9667722.tar.gz |
codegen: Fix array ownership transfer
-rw-r--r-- | codegen/valaccodeassignmentmodule.vala | 22 | ||||
-rw-r--r-- | codegen/valaccodebasemodule.vala | 33 | ||||
-rw-r--r-- | tests/basic-types/arrays.vala | 12 |
3 files changed, 55 insertions, 12 deletions
diff --git a/codegen/valaccodeassignmentmodule.vala b/codegen/valaccodeassignmentmodule.vala index ed25014f0..2b009d517 100644 --- a/codegen/valaccodeassignmentmodule.vala +++ b/codegen/valaccodeassignmentmodule.vala @@ -208,17 +208,27 @@ public class Vala.CCodeAssignmentModule : CCodeMemberAccessModule { ccode.add_assignment (get_cvalue_ (lvalue), get_cvalue_ (value)); - if (array_type != null) { - if (!variable.no_array_length && !variable.array_null_terminated) { + if (array_type != null && !variable.no_array_length) { + var glib_value = (GLibValue) value; + if (glib_value.array_length_cvalues != null) { for (int dim = 1; dim <= array_type.rank; dim++) { ccode.add_assignment (get_array_length_cvalue (lvalue, dim), get_array_length_cvalue (value, dim)); } - if (array_type.rank == 1) { - if (get_array_size_cvalue (lvalue) != null) { - ccode.add_assignment (get_array_size_cvalue (lvalue), get_array_length_cvalue (value, 1)); - } + } else if (glib_value.array_null_terminated) { + requires_array_length = true; + var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length")); + len_call.add_argument (get_cvalue_ (value)); + + ccode.add_assignment (get_array_length_cvalue (lvalue, 1), len_call); + } else { + for (int dim = 1; dim <= array_type.rank; dim++) { + ccode.add_assignment (get_array_length_cvalue (lvalue, dim), new CCodeConstant ("-1")); } } + + if (array_type.rank == 1 && get_array_size_cvalue (lvalue) != null) { + ccode.add_assignment (get_array_size_cvalue (lvalue), get_array_length_cvalue (lvalue, 1)); + } } var delegate_type = variable.variable_type as DelegateType; diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 867b35cbc..3e5ec98b5 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -4775,22 +4775,39 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } public override void visit_reference_transfer_expression (ReferenceTransferExpression expr) { - /* (tmp = var, var = null, tmp) */ + /* tmp = expr.inner; expr.inner = NULL; expr = tmp; */ var temp_decl = get_temp_variable (expr.value_type, true, expr, false); emit_temp_var (temp_decl); var cvar = get_variable_cexpression (temp_decl.name); ccode.add_assignment (cvar, get_cvalue (expr.inner)); - if (!(expr.value_type is DelegateType)) { - ccode.add_assignment (get_cvalue (expr.inner), new CCodeConstant ("NULL")); - } set_cvalue (expr, cvar); var array_type = expr.value_type as ArrayType; if (array_type != null) { - for (int dim = 1; dim <= array_type.rank; dim++) { - append_array_length (expr, get_array_length_cexpression (expr.inner, dim)); + var value = (GLibValue) expr.inner.target_value; + if (value.array_length_cvalues != null) { + for (int dim = 1; dim <= array_type.rank; dim++) { + var len_decl = get_temp_variable (int_type, true, expr, false); + emit_temp_var (len_decl); + ccode.add_assignment (get_variable_cexpression (len_decl.name), get_array_length_cexpression (expr.inner, dim)); + append_array_length (expr, get_variable_cexpression (len_decl.name)); + } + } else if (value.array_null_terminated) { + requires_array_length = true; + var len_decl = get_temp_variable (int_type, true, expr, false); + emit_temp_var (len_decl); + + var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length")); + len_call.add_argument (get_cvalue_ (value)); + + ccode.add_assignment (get_variable_cexpression (len_decl.name), len_call); + append_array_length (expr, get_variable_cexpression (len_decl.name)); + } else { + for (int dim = 1; dim <= array_type.rank; dim++) { + append_array_length (expr, new CCodeConstant ("-1")); + } } } @@ -4812,6 +4829,10 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { set_delegate_target_destroy_notify (expr, target_destroy_notify_cvar); } } + + if (!(expr.value_type is DelegateType)) { + ccode.add_assignment (get_cvalue (expr.inner), new CCodeConstant ("NULL")); + } } public override void visit_binary_expression (BinaryExpression expr) { diff --git a/tests/basic-types/arrays.vala b/tests/basic-types/arrays.vala index 0b80cf6ab..27efbad29 100644 --- a/tests/basic-types/arrays.vala +++ b/tests/basic-types/arrays.vala @@ -1,3 +1,9 @@ +[CCode (array_length = false, array_null_terminated = true)] +int[] foo; + +[CCode (array_length = false)] +int[] bar; + void test_integer_array () { // declaration and initialization int[] a = { 42 }; @@ -80,10 +86,16 @@ void test_static_array () { assert (a[0] == 23 && a[1] == 34); } +void test_reference_transfer () { + var baz = (owned) foo; + baz = (owned) bar; +} + void main () { test_integer_array (); test_string_array (); test_array_pass (); test_static_array (); + test_reference_transfer (); } |