[vala/0.50] codegen: Don't leak memory on internal value comparison of property setter
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/0.50] codegen: Don't leak memory on internal value comparison of property setter
- Date: Sat, 2 Jan 2021 12:33:07 +0000 (UTC)
commit 44792c59c176eef6f707e2a2b095d38f944716c7
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 68c31946c..32e90f517 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1942,10 +1942,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"))));
@@ -1953,7 +1957,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"));
@@ -1973,12 +1977,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 ba21f788a..64100bfa5 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -452,6 +452,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]