summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Bruno <lucabru@src.gnome.org>2011-03-17 18:29:28 +0100
committerLuca Bruno <lucabru@src.gnome.org>2011-04-30 11:32:53 +0200
commitc3719316c34ef3e1e926dc68cd2ac8cfb9667722 (patch)
tree02afc47857b543a6d9daf620bcb30f00434cc648
parent8eb920394daa627882de1f7eec43dac2f42fafe5 (diff)
downloadvala-c3719316c34ef3e1e926dc68cd2ac8cfb9667722.tar.gz
codegen: Fix array ownership transfer
-rw-r--r--codegen/valaccodeassignmentmodule.vala22
-rw-r--r--codegen/valaccodebasemodule.vala33
-rw-r--r--tests/basic-types/arrays.vala12
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 ();
}