Commit fb9c60d0 authored by Raffaele Sandrini's avatar Raffaele Sandrini Committed by Raffaele Sandrini

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
parent 3956d849
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>
......
......@@ -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"));
......
......@@ -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) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment