]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Properly destroy elements of an inline struct array
authorRico Tzschichholz <ricotz@ubuntu.com>
Mon, 27 Jul 2020 11:36:56 +0000 (13:36 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Wed, 29 Jul 2020 13:07:42 +0000 (15:07 +0200)
Fixes https://gitlab.gnome.org/GNOME/vala/issues/365

codegen/valaccodearraymodule.vala
codegen/valaccodebasemodule.vala
tests/Makefile.am
tests/arrays/inline-struct.vala [new file with mode: 0644]

index 0a2d614f408ab60e3a95aec2f5519179ef2a3e00..0c01facaece6f50163141c492fdebd99635953a9 100644 (file)
@@ -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"));
index 72a059c8c550acd666305c86d741e4d27aa13be7..666cd6e44b05501658440754918cbdf11c744c05 100644 (file)
@@ -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;
        }
index bacb16fa43f3167dd1dc9ea8b01496097f12c3c6..42e7c95fc61e958ac1fff469c8044776b6ebaae2 100644 (file)
@@ -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 (file)
index 0000000..a8f0510
--- /dev/null
@@ -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));
+       }
+}