+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,
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>
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"));
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) {