diff options
author | Raffaele Sandrini <raffaele@sandrini.ch> | 2007-09-20 21:23:19 +0000 |
---|---|---|
committer | Raffaele Sandrini <rasa@src.gnome.org> | 2007-09-20 21:23:19 +0000 |
commit | fb9c60d0578c3b5294843c54ebea898a244d64b5 (patch) | |
tree | 10d879346f39e2ecd90e4721e1f87075858789fd | |
parent | 3956d8490a4921871380fa5bb41471294cf5e63f (diff) | |
download | vala-fb9c60d0578c3b5294843c54ebea898a244d64b5.tar.gz |
Fix memory leak with non reference counting reference types in property
2007-09-20 Raffaele Sandrini <raffaele@sandrini.ch>
* vala/valasemanticanalyzer.vala, gobject/valaccodegenerator.vala:
Fix memory leak with non reference counting reference types in
property getters, now we enforce an explicit ownership transfer in
such a case, fixes bug 472904
svn path=/trunk/; revision=625
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | gobject/valaccodegenerator.vala | 11 | ||||
-rw-r--r-- | vala/valasemanticanalyzer.vala | 15 |
3 files changed, 34 insertions, 1 deletions
@@ -1,3 +1,10 @@ +2007-09-20 Raffaele Sandrini <raffaele@sandrini.ch> + + * vala/valasemanticanalyzer.vala, gobject/valaccodegenerator.vala: + Fix memory leak with non reference counting reference types in + property getters, now we enforce an explicit ownership transfer in + such a case, fixes bug 472904 + 2007-09-20 Jürg Billeter <j@bitron.ch> * vala/parser.y, vala/vala.h, vala/valacodecontext.vala, @@ -9,7 +16,7 @@ 2007-09-20 Raffaele Sandrini <raffaele@sandrini.ch> * vala/parser.y: Add support for ownership transfer with properties - using the HASH (#) modifier. e.g. public string!# foo { get; set; } + using the HASH (#) modifier. e.g. public string!# foo { get; set; } 2007-09-20 Raffaele Sandrini <raffaele@sandrini.ch> diff --git a/gobject/valaccodegenerator.vala b/gobject/valaccodegenerator.vala index 8754f01a9..b3f8b35f3 100644 --- a/gobject/valaccodegenerator.vala +++ b/gobject/valaccodegenerator.vala @@ -589,6 +589,17 @@ public class Vala.CCodeGenerator : CodeGenerator { ccall.add_argument (new CCodeConstant ("NULL")); block.add_statement (new CCodeExpressionStatement (ccall)); + + // HACK: decrement the refcount before returning the value to simulate a weak reference getter function + if (prop.type_reference.data_type.is_reference_counting ()) { + var unref_cond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("value"), new CCodeConstant ("NULL")); + var unref_function = new CCodeFunctionCall (get_destroy_func_expression (prop.type_reference)); + unref_function.add_argument (new CCodeIdentifier ("value")); + var unref_block = new CCodeBlock (); + unref_block.add_statement (new CCodeExpressionStatement (unref_function)); + block.add_statement (new CCodeIfStatement (unref_cond, unref_block)); + } + block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("value"))); } else { var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_set")); diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 0da61096c..16d083de5 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -549,6 +549,21 @@ public class Vala.SemanticAnalyzer : CodeVisitor { prop.accept_children (this); + /* abstract/virtual properties using reference types without + * reference counting need to transfer ownership of their + * return values because of limitations in the GObject property + * system (g_object_get always returns strong references). + * Reference counting types can simulate to return a weak + * reference */ + if ((prop.is_abstract || prop.is_virtual) && + prop.type_reference.data_type.is_reference_type () && + !prop.type_reference.data_type.is_reference_counting () && + !prop.type_reference.transfers_ownership) + { + Report.error (prop.source_reference, "%s: abstract or virtual properties using reference types not supporting reference counting, like `%s', have to mark their return value to transfer ownership.".printf (prop.get_full_name (), prop.type_reference.data_type.get_full_name ())); + prop.error = true; + } + current_symbol = current_symbol.parent_symbol; if (prop.type_reference.data_type != null) { |