From: Rico Tzschichholz Date: Wed, 22 Mar 2017 18:16:06 +0000 (+0100) Subject: codegen: Don't leak target-reference when casting/assigning owned delegates X-Git-Tag: 0.36.1~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=74aa6d2ab5d8c0a787ac8d9003c50233d5765a6e;p=thirdparty%2Fvala.git codegen: Don't leak target-reference when casting/assigning owned delegates Regression of 6d07669384cdb70c3c657dba67d5048212f25da9 https://bugzilla.gnome.org/show_bug.cgi?id=780426 --- diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala index dd7a2aea7..6bb5cb22a 100644 --- a/codegen/valaccodememberaccessmodule.vala +++ b/codegen/valaccodememberaccessmodule.vala @@ -100,9 +100,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule { var ref_call = new CCodeFunctionCall (get_dup_func_expression (expr.inner.value_type, expr.source_reference)); ref_call.add_argument (delegate_target); delegate_target = ref_call; - if (delegate_type != null && delegate_type.is_disposable ()) { - set_delegate_target_destroy_notify (expr, get_destroy_func_expression (expr.inner.value_type)); - } + set_delegate_target_destroy_notify (expr, get_destroy_func_expression (expr.inner.value_type)); } set_delegate_target (expr, delegate_target); } diff --git a/tests/Makefile.am b/tests/Makefile.am index 829df93be..e368b6b95 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -145,6 +145,7 @@ TESTS = \ structs/bug749952.vala \ structs/bug775761.vala \ structs/bug777194.vala \ + delegates/casting.vala \ delegates/delegates.vala \ delegates/reference_transfer.vala \ delegates/bug539166.vala \ diff --git a/tests/delegates/casting.vala b/tests/delegates/casting.vala new file mode 100644 index 000000000..5ebbf116b --- /dev/null +++ b/tests/delegates/casting.vala @@ -0,0 +1,90 @@ +delegate void FooFunc (); + +[CCode (has_target = false)] +delegate void FooFuncTargetless (); + +class Foo : Object { + public Foo () { + baz (func); + assert (ref_count == 1); + + bar (func); + assert (ref_count == 1); + + baz ((FooFunc) func); + assert (ref_count == 1); + + bar ((FooFunc) func); + assert (ref_count == 1); + + man ((FooFuncTargetless) func); + assert (ref_count == 1); + + maz ((FooFuncTargetless) func); + assert (ref_count == 1); + } + + public void func () { + } + + void baz (FooFunc f) { + assert (ref_count == 1); + } + + void bar (owned FooFunc f) { + assert (ref_count == 2); + } + + void man (FooFuncTargetless f) { + assert (ref_count == 1); + } + + void maz (owned FooFuncTargetless f) { + assert (ref_count == 1); + } +} + +void func () { +} + +void main () { + var foo = new Foo (); + assert (foo.ref_count == 1); + + FooFunc f0 = foo.func; + assert (foo.ref_count == 2); + f0 = null; + assert (foo.ref_count == 1); + + var f1 = (FooFunc) foo.func; + assert (foo.ref_count == 2); + f1 = null; + assert (foo.ref_count == 1); + + unowned FooFunc f2 = foo.func; + assert (foo.ref_count == 1); + f2 = null; + assert (foo.ref_count == 1); + + unowned FooFunc f3 = (FooFunc) foo.func; + assert (foo.ref_count == 1); + f3 = null; + assert (foo.ref_count == 1); + + var f4 = (FooFuncTargetless) foo.func; + assert (foo.ref_count == 1); + f4 = null; + assert (foo.ref_count == 1); + + FooFuncTargetless f5 = func; + f5 = null; + + var f6 = (FooFuncTargetless) func; + f6 = null; + + unowned FooFuncTargetless f7 = func; + f7 = null; + + unowned FooFuncTargetless f8 = (FooFuncTargetless) func; + f8 = null; +}