]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Fix array ownership transfer
authorLuca Bruno <lucabru@src.gnome.org>
Thu, 17 Mar 2011 17:29:28 +0000 (18:29 +0100)
committerLuca Bruno <lucabru@src.gnome.org>
Sat, 30 Apr 2011 09:32:53 +0000 (11:32 +0200)
codegen/valaccodeassignmentmodule.vala
codegen/valaccodebasemodule.vala
tests/basic-types/arrays.vala

index ed25014f0d4892770fb0c720e5d52295f3d8b600..2b009d517331ad0d1851c1b405657a61a01547a4 100644 (file)
@@ -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;
index 867b35cbcfd872543be9bee4476b6af6d5d1c11c..3e5ec98b595272b73b6358655fc9855cc5501461 100644 (file)
@@ -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) {
index 0b80cf6ab3a33de5cc64fcf632c07b1b7d4d4193..27efbad295ba0a1cc26c3130f92837d27c762be8 100644 (file)
@@ -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 ();
 }