From: Rico Tzschichholz Date: Mon, 27 Jul 2020 11:36:56 +0000 (+0200) Subject: codegen: Properly destroy elements of an inline struct array X-Git-Tag: 0.40.24~46 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4fee801d5fbdfdf44c6e7016bf3dd734074bddb3;p=thirdparty%2Fvala.git codegen: Properly destroy elements of an inline struct array Fixes https://gitlab.gnome.org/GNOME/vala/issues/365 --- diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala index 0a2d614f4..0c01facae 100644 --- a/codegen/valaccodearraymodule.vala +++ b/codegen/valaccodearraymodule.vala @@ -251,6 +251,36 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule { return cname; } + public override string? append_struct_array_destroy (Struct st) { + string cname = "_vala_%s_array_destroy".printf (get_ccode_name (st)); + + if (cfile.add_declaration (cname)) { + return cname; + } + + var fun = new CCodeFunction (cname, "void"); + fun.modifiers = CCodeModifiers.STATIC; + fun.add_parameter (new CCodeParameter ("array", "%s *".printf (get_ccode_name (st)))); + fun.add_parameter (new CCodeParameter ("array_length", get_ccode_name (int_type))); + + push_function (fun); + + var ccondarr = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("array"), new CCodeConstant ("NULL")); + ccode.open_if (ccondarr); + + ccode.add_declaration (get_ccode_name (int_type), new CCodeVariableDeclarator ("i")); + append_struct_array_free_loop (st); + + ccode.close (); + + pop_function (); + + cfile.add_function_declaration (fun); + cfile.add_function (fun); + + return cname; + } + void append_vala_array_free_loop () { var cforinit = new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")); var cforcond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("array_length")); @@ -452,20 +482,20 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule { } public override CCodeExpression destroy_value (TargetValue value, bool is_macro_definition = false) { - var type = value.value_type; - - if (type is ArrayType) { - var array_type = (ArrayType) type; + unowned ArrayType? array_type = value.value_type as ArrayType; - if (!array_type.fixed_length) { - return base.destroy_value (value, is_macro_definition); + if (array_type != null && array_type.fixed_length) { + unowned Struct? st = array_type.element_type.type_symbol as Struct; + if (st != null && !array_type.element_type.nullable) { + var ccall = new CCodeFunctionCall (new CCodeIdentifier (append_struct_array_destroy (st))); + ccall.add_argument (get_cvalue_ (value)); + ccall.add_argument (get_ccodenode (array_type.length)); + return ccall; } requires_array_free = true; - var ccall = new CCodeFunctionCall (get_destroy_func_expression (type)); - - ccall = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_destroy")); + var ccall = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_destroy")); ccall.add_argument (get_cvalue_ (value)); ccall.add_argument (get_ccodenode (array_type.length)); ccall.add_argument (new CCodeCastExpression (get_destroy_func_expression (array_type.element_type), "GDestroyNotify")); diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 72a059c8c..666cd6e44 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -3462,6 +3462,10 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { return destroy_func; } + public virtual string? append_struct_array_destroy (Struct st) { + return null; + } + public virtual string? append_struct_array_free (Struct st) { return null; } diff --git a/tests/Makefile.am b/tests/Makefile.am index bacb16fa4..42e7c95fc 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -82,6 +82,7 @@ TESTS = \ arrays/inline-local-instantiation.test \ arrays/inline-local-variable.test \ arrays/inline-parameter.test \ + arrays/inline-struct.vala \ arrays/inline-struct-field.test \ arrays/in-operator-with-boxed-needle.vala \ arrays/length-inline-assignment.vala \ diff --git a/tests/arrays/inline-struct.vala b/tests/arrays/inline-struct.vala new file mode 100644 index 000000000..a8f05103b --- /dev/null +++ b/tests/arrays/inline-struct.vala @@ -0,0 +1,18 @@ +[CCode (has_type_id = false)] +public struct FooStruct { + public uint8 i; + public string s; +} + +void main () { + { + FooStruct array[2]; + array[0] = { 23, "foo"}; + array[1] = { 42, "bar"}; + } + { + GLib.Value array[2]; + array[0].init (typeof (int)); + array[1].init (typeof (string)); + } +}