]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Object.new will ref_sink() the returned instance if it is floating
authorLuca Bruno <lethalman88@gmail.com>
Sun, 28 Feb 2010 14:06:56 +0000 (15:06 +0100)
committerJürg Billeter <j@bitron.ch>
Sat, 13 Mar 2010 17:13:32 +0000 (18:13 +0100)
Fixes bug 555006.

codegen/valagobjectmodule.vala

index 462c38a0676524e4f1add18fb3b6ec08b551cc9b..388ef590372dacb8f4c26367957910cbeb83d9a5 100644 (file)
@@ -713,23 +713,44 @@ internal class Vala.GObjectModule : GTypeModule {
        }
 
        public override void visit_method_call (MethodCall expr) {
-               if (expr.call is MemberAccess && expr.call.symbol_reference == gobject_type) {
-                       // Object (...) chain up
-                       // check it's only used with valid properties
-                       foreach (var arg in expr.get_argument_list ()) {
-                               var named_argument = arg as NamedArgument;
-                               if (named_argument == null) {
-                                       Report.error (arg.source_reference, "Named argument expected");
-                                       break;
-                               }
-                               var prop = SemanticAnalyzer.symbol_lookup_inherited (current_class, named_argument.name) as Property;
-                               if (prop == null) {
-                                       Report.error (arg.source_reference, "Property `%s' not found in `%s'".printf (named_argument.name, current_class.get_full_name ()));
-                                       break;
-                               }
-                               if (!arg.value_type.compatible (prop.property_type)) {
-                                       Report.error (arg.source_reference, "Cannot convert from `%s' to `%s'".printf (arg.value_type.to_string (), prop.property_type.to_string ()));
-                                       break;
+               if (expr.call is MemberAccess) {
+                       var ma = expr.call as MemberAccess;
+                       if (ma.inner != null && ma.inner.symbol_reference == gobject_type && ma.member_name == "new") {
+                               // Object.new (...) creation
+                               // runtime check to ref_sink the instance if it's a floating type
+                               base.visit_method_call (expr);
+
+                               var ccomma = new CCodeCommaExpression ();
+                               var temp_var = get_temp_variable (expr.value_type, false, expr, false);
+                               temp_vars.insert (0, temp_var);
+                               ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), (CCodeExpression) expr.ccodenode));
+
+                               var is_floating_ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_is_floating"));
+                               is_floating_ccall.add_argument (get_variable_cexpression (temp_var.name));
+                               var sink_ref_ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_ref_sink"));
+                               sink_ref_ccall.add_argument (get_variable_cexpression (temp_var.name));
+                               ccomma.append_expression (new CCodeConditionalExpression (is_floating_ccall, sink_ref_ccall, get_variable_cexpression (temp_var.name)));
+
+                               expr.ccodenode = ccomma;
+                               return;
+                       } else if (ma.symbol_reference == gobject_type) {
+                               // Object (...) chain up
+                               // check it's only used with valid properties
+                               foreach (var arg in expr.get_argument_list ()) {
+                                       var named_argument = arg as NamedArgument;
+                                       if (named_argument == null) {
+                                               Report.error (arg.source_reference, "Named argument expected");
+                                               break;
+                                       }
+                                       var prop = SemanticAnalyzer.symbol_lookup_inherited (current_class, named_argument.name) as Property;
+                                       if (prop == null) {
+                                               Report.error (arg.source_reference, "Property `%s' not found in `%s'".printf (named_argument.name, current_class.get_full_name ()));
+                                               break;
+                                       }
+                                       if (!arg.value_type.compatible (prop.property_type)) {
+                                               Report.error (arg.source_reference, "Cannot convert from `%s' to `%s'".printf (arg.value_type.to_string (), prop.property_type.to_string ()));
+                                               break;
+                                       }
                                }
                        }
                }