]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Fix memory leak when using object initializer for properties c0e955db075d3d155782c167a0abb81e0dce5f59
authorRico Tzschichholz <ricotz@ubuntu.com>
Fri, 20 Jan 2017 17:09:38 +0000 (18:09 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Sun, 12 Feb 2017 18:23:52 +0000 (19:23 +0100)
Assigning values to properties this way leads to a ref/copy of the source
and therefore requires a unref/destroy afterwards.

https://bugzilla.gnome.org/show_bug.cgi?id=766739

codegen/valaccodebasemodule.vala
tests/Makefile.am
tests/objects/bug766739.vala [new file with mode: 0644]

index f979dab46f01b5b3da04eb2102e4236158981d02..e8bb29f51273103972180283da6d2c6b49e52aa1 100644 (file)
@@ -4846,6 +4846,10 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                        inst_ma.value_type = expr.type_reference;
                                        set_cvalue (inst_ma, instance);
                                        store_property ((Property) init.symbol_reference, inst_ma, init.initializer.target_value);
+                                       // FIXME Do not ref/copy in the first place
+                                       if (requires_destroy (init.initializer.target_value.value_type)) {
+                                               ccode.add_expression (destroy_value (init.initializer.target_value));
+                                       }
                                }
                        }
 
index 8e977db5190f2aeefc91866bbcc20bee65f87606..cd8aa0859e18248823e4371242e4737667d3df07 100644 (file)
@@ -199,6 +199,7 @@ TESTS = \
        objects/bug773956-2.test \
        objects/bug615830-1.test \
        objects/bug615830-2.test \
+       objects/bug766739.vala \
        errors/errors.vala \
        errors/bug567181.vala \
        errors/bug579101.vala \
diff --git a/tests/objects/bug766739.vala b/tests/objects/bug766739.vala
new file mode 100644 (file)
index 0000000..55e9746
--- /dev/null
@@ -0,0 +1,79 @@
+struct FooStruct {
+       public int bar;
+}
+
+class FooClass {
+       public int bar = 42;
+}
+
+
+class Bar {
+       public int f_simple;
+       public string f_string;
+       public string[] f_array;
+       public FooStruct f_struct;
+       public FooClass f_class;
+
+       public unowned string fu_string;
+       public unowned string[] fu_array;
+       public unowned FooStruct? fu_struct;
+       public unowned FooClass fu_class;
+
+       public int p_simple { get; set; }
+       public string p_string { get; set; }
+       public string[] p_array { get; set; }
+       public FooStruct p_struct { get; set; }
+       public FooClass p_class { get; set; }
+}
+
+
+void main () {
+       FooStruct fs = { 42 };
+       var fc = new FooClass ();
+       string s = "foo";
+       string[] a = { "foo", "bar" };
+
+       var bar = new Bar () {
+               f_simple = 42,
+               f_string = s,
+               f_array = a,
+               f_struct = fs,
+               f_class = fc,
+
+               fu_string = s,
+               fu_array = a,
+               fu_struct = fs,
+               fu_class = fc,
+
+               p_simple = 42,
+               p_string = s,
+               p_array = a,
+               p_struct = fs,
+               p_class = fc
+       };
+
+       assert (bar.f_simple == 42);
+       assert (bar.f_string == "foo");
+       assert (bar.f_array[1] == "bar");
+       assert (bar.f_struct.bar == 42);
+       assert (bar.f_class == fc);
+
+       assert (bar.fu_string == "foo");
+       assert (bar.fu_array[1] == "bar");
+       assert (bar.fu_struct == fs);
+       assert (bar.fu_class == fc);
+
+       assert (bar.p_simple == 42);
+       assert (bar.p_string == "foo");
+       assert (bar.p_array[1] == "bar");
+       assert (bar.p_struct.bar == 42);
+       assert (bar.p_class == fc);
+
+       bar = null;
+
+       assert (fs.bar == 42);
+       assert (fc.bar == 42);
+       assert (s == "foo");
+       assert (a[1] == "bar");
+}
+