[vala] codegen: Fix memory leak when using object initializer for properties



commit c0e955db075d3d155782c167a0abb81e0dce5f59
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Fri Jan 20 18:09:38 2017 +0100

    codegen: Fix memory leak when using object initializer for properties
    
    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 |    4 ++
 tests/Makefile.am                |    1 +
 tests/objects/bug766739.vala     |   79 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 84 insertions(+), 0 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index f979dab..e8bb29f 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -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));
+                                       }
                                }
                        }
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8e977db..cd8aa08 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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
index 0000000..55e9746
--- /dev/null
+++ b/tests/objects/bug766739.vala
@@ -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");
+}
+


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]