[vala/staging] codegen: Don't leak memory on internal value comparison of property setter



commit b11a2a220698b8c96cccbab12d125129abcd7f4f
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Fri Jan 1 11:10:41 2021 +0100

    codegen: Don't leak memory on internal value comparison of property setter

 codegen/valaccodebasemodule.vala                | 20 +++++++--
 tests/Makefile.am                               |  1 +
 tests/objects/property-notify-owned-getter.vala | 54 +++++++++++++++++++++++++
 3 files changed, 72 insertions(+), 3 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index b7db31835..d6463a8aa 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1948,10 +1948,14 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                        get_call.add_argument (new CCodeIdentifier (is_virtual ? "base" : 
"self"));
 
                                        if (property_type is ArrayType && get_ccode_array_length (prop)) {
+                                               ccode.add_declaration (get_ccode_name (property_type), new 
CCodeVariableDeclarator ("old_value"));
                                                ccode.add_declaration (get_ccode_array_length_type (prop), 
new CCodeVariableDeclarator ("old_value_length"));
                                                get_call.add_argument (new CCodeUnaryExpression 
(CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("old_value_length")));
-                                               ccode.open_if (new CCodeBinaryExpression 
(CCodeBinaryOperator.INEQUALITY, get_call, new CCodeIdentifier ("value")));
+                                               ccode.add_assignment (new CCodeIdentifier ("old_value"), 
get_call);
+                                               ccode.open_if (new CCodeBinaryExpression 
(CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("old_value"), new CCodeIdentifier ("value")));
                                        } else if (property_type.compatible (string_type)) {
+                                               ccode.add_declaration (get_ccode_name (property_type), new 
CCodeVariableDeclarator ("old_value"));
+                                               ccode.add_assignment (new CCodeIdentifier ("old_value"), 
get_call);
                                                CCodeFunctionCall ccall;
                                                if (context.profile == Profile.POSIX) {
                                                        ccall = new CCodeFunctionCall (new CCodeIdentifier 
(generate_cmp_wrapper (new CCodeIdentifier ("strcmp"))));
@@ -1959,7 +1963,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                                        ccall = new CCodeFunctionCall (new CCodeIdentifier 
("g_strcmp0"));
                                                }
                                                ccall.add_argument (new CCodeIdentifier ("value"));
-                                               ccall.add_argument (get_call);
+                                               ccall.add_argument (new CCodeIdentifier ("old_value"));
                                                ccode.open_if (new CCodeBinaryExpression 
(CCodeBinaryOperator.INEQUALITY, ccall, new CCodeConstant ("0")));
                                        } else if (property_type is StructValueType) {
                                                ccode.add_declaration (get_ccode_name (property_type), new 
CCodeVariableDeclarator ("old_value"));
@@ -1979,12 +1983,22 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                                }
                                                ccode.open_if (new CCodeBinaryExpression 
(CCodeBinaryOperator.INEQUALITY, ccall, new CCodeConstant ("TRUE")));
                                        } else {
-                                               ccode.open_if (new CCodeBinaryExpression 
(CCodeBinaryOperator.INEQUALITY, get_call, new CCodeIdentifier ("value")));
+                                               ccode.add_declaration (get_ccode_name (property_type), new 
CCodeVariableDeclarator ("old_value"));
+                                               ccode.add_assignment (new CCodeIdentifier ("old_value"), 
get_call);
+                                               ccode.open_if (new CCodeBinaryExpression 
(CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("old_value"), new CCodeIdentifier ("value")));
                                        }
 
                                        acc.body.emit (this);
                                        ccode.add_expression (notify_call);
                                        ccode.close ();
+
+                                       if (prop.get_accessor.value_type.is_disposable ()) {
+                                               var old_value = new GLibValue (prop.get_accessor.value_type, 
new CCodeIdentifier ("old_value"), true);
+                                               if (property_type is ArrayType && get_ccode_array_length 
(prop)) {
+                                                       old_value.append_array_length_cvalue (new 
CCodeIdentifier ("old_value_length"));
+                                               }
+                                               ccode.add_expression (destroy_value (old_value));
+                                       }
                                } else {
                                        acc.body.emit (this);
                                        ccode.add_expression (notify_call);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3d41840ed..8e5935cff 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -453,6 +453,7 @@ TESTS = \
        objects/property-base-access.vala \
        objects/property-enum.vala \
        objects/property-notify.vala \
+       objects/property-notify-owned-getter.vala \
        objects/property-ownership.vala \
        objects/property-read-only-auto.vala \
        objects/property-read-only-write.test \
diff --git a/tests/objects/property-notify-owned-getter.vala b/tests/objects/property-notify-owned-getter.vala
new file mode 100644
index 000000000..7633abaa1
--- /dev/null
+++ b/tests/objects/property-notify-owned-getter.vala
@@ -0,0 +1,54 @@
+class Bar : Object {
+}
+
+struct Manam {
+       public string s;
+}
+
+class Foo : Object {
+       public Bar o { owned get; set; }
+
+       public Manam st { owned get; set; }
+
+       public Manam? stn { owned get; set; }
+
+       public string s { owned get; set; }
+
+       public string[] strv { owned get; set; }
+
+       construct {
+               o = bar;
+               st = { "foo" };
+               stn = { "bar" };
+               s = "foo";
+               strv = { "foo", "bar" };
+       }
+}
+
+Bar bar;
+
+void main () {
+       bar = new Bar ();
+       assert (bar.ref_count == 1);
+
+       var foo = new Foo ();
+       assert (bar.ref_count == 2);
+       foo.o = bar;
+       assert (bar.ref_count == 2);
+
+       assert (foo.st.s == "foo");
+       foo.st = { "manam" };
+       assert (foo.st.s == "manam");
+
+       assert (foo.stn.s == "bar");
+       foo.stn = { "minim" };
+       assert (foo.stn.s == "minim");
+
+       assert (foo.s == "foo");
+       foo.s = "manam";
+       assert (foo.s == "manam");
+
+       assert (foo.strv[1] == "bar");
+       foo.strv = { "manam", "minim" };
+       assert (foo.strv[1] == "minim");
+}


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