From: Rico Tzschichholz Date: Tue, 31 Mar 2020 12:55:59 +0000 (+0200) Subject: codegen: Correct field declaration for captured inline-allocated array X-Git-Tag: 0.49.1~209 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aa56462e5a25e6843faf4353ca396a069cd431e4;p=thirdparty%2Fvala.git codegen: Correct field declaration for captured inline-allocated array Also pass proper size to memset for local temp variables of inline-allocated arrays in asynchronous context. Fixes https://gitlab.gnome.org/GNOME/vala/issues/954 --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index db3c4f4e0..677285d51 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -1999,7 +1999,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { if (!param.variable_type.value_owned) { param_type.value_owned = !no_implicit_copy (param.variable_type); } - data.add_field (get_ccode_name (param_type), get_ccode_name (param)); + data.add_field (get_ccode_name (param_type), get_ccode_name (param), 0, get_ccode_declarator_suffix (param_type)); // create copy if necessary as captured variables may need to be kept alive param.captured = false; @@ -2008,7 +2008,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { var array_type = param.variable_type as ArrayType; var deleg_type = param.variable_type as DelegateType; - if (array_type != null && get_ccode_array_length (param)) { + if (array_type != null && get_ccode_array_length (param) && !((ArrayType) array_type).fixed_length) { var length_ctype = get_ccode_array_length_type (param); for (int dim = 1; dim <= array_type.rank; dim++) { data.add_field (length_ctype, get_variable_array_length_cname (param, dim)); @@ -3792,7 +3792,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { public void emit_temp_var (LocalVariable local, bool on_error = false) { var init = (!local.name.has_prefix ("*") && local.init); if (is_in_coroutine ()) { - closure_struct.add_field (get_ccode_name (local.variable_type), local.name); + closure_struct.add_field (get_ccode_name (local.variable_type), local.name, 0, get_ccode_declarator_suffix (local.variable_type)); // even though closure struct is zerod, we need to initialize temporary variables // as they might be used multiple times when declared in a loop @@ -3804,7 +3804,12 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { var memset_call = new CCodeFunctionCall (new CCodeIdentifier ("memset")); memset_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (local.name))); memset_call.add_argument (new CCodeConstant ("0")); - memset_call.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (get_ccode_name (local.variable_type)))); + CCodeExpression? size = null; + requires_memset_init (local, out size); + if (size == null) { + size = new CCodeIdentifier ("sizeof (%s)".printf (get_ccode_name (local.variable_type))); + } + memset_call.add_argument (size); ccode.add_expression (memset_call); } else { ccode.add_assignment (get_variable_cexpression (local.name), initializer); @@ -6285,11 +6290,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { public bool requires_memset_init (Variable variable, out CCodeExpression? size) { unowned ArrayType? array_type = variable.variable_type as ArrayType; - if (array_type != null && array_type.fixed_length && !is_constant_ccode (array_type.length)) { + if (array_type != null && array_type.fixed_length) { var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof")); sizeof_call.add_argument (new CCodeIdentifier (get_ccode_name (array_type.element_type))); size = new CCodeBinaryExpression (CCodeBinaryOperator.MUL, get_ccodenode (array_type.length), sizeof_call); - return true; + return !is_constant_ccode (array_type.length); } size = null; return false; diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala index d74431f71..7a545ea92 100644 --- a/codegen/valagasyncmodule.vala +++ b/codegen/valagasyncmodule.vala @@ -48,11 +48,11 @@ public class Vala.GAsyncModule : GtkModule { foreach (Parameter param in m.get_parameters ()) { var param_type = param.variable_type.copy (); param_type.value_owned = true; - data.add_field (get_ccode_name (param_type), get_ccode_name (param)); + data.add_field (get_ccode_name (param_type), get_ccode_name (param), 0, get_ccode_declarator_suffix (param_type)); if (param.variable_type is ArrayType) { var array_type = (ArrayType) param.variable_type; - if (get_ccode_array_length (param)) { + if (get_ccode_array_length (param) && !((ArrayType) array_type).fixed_length) { var length_ctype = get_ccode_array_length_type (param); for (int dim = 1; dim <= array_type.rank; dim++) { data.add_field (length_ctype, get_variable_array_length_cname (param, dim)); diff --git a/tests/Makefile.am b/tests/Makefile.am index c0018fdf7..7b8d40bcb 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -540,6 +540,7 @@ TESTS = \ asynchronous/bug792660.vala \ asynchronous/bug792942.vala \ asynchronous/bug793158.vala \ + asynchronous/captured-fixed-array.vala \ asynchronous/catch-error-scope.vala \ asynchronous/catch-in-finally.vala \ asynchronous/creation-missing-yield.test \ diff --git a/tests/asynchronous/captured-fixed-array.vala b/tests/asynchronous/captured-fixed-array.vala new file mode 100644 index 000000000..30a9c38be --- /dev/null +++ b/tests/asynchronous/captured-fixed-array.vala @@ -0,0 +1,14 @@ +async void foo (int array_param[3]) { + int array[] = { 23, 42 }; + + assert (array.length == 2); + assert (array[1] == 42); + + assert (array_param.length == 3); + assert (array_param[2] == 4711); +} + +void main() { + int array[3] = { 42, 23, 4711 }; + foo.begin (array); +}