]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Fix memory leak when freeing nullable structs without free function
authorJürg Billeter <j@bitron.ch>
Fri, 20 Aug 2010 14:52:21 +0000 (16:52 +0200)
committerJürg Billeter <j@bitron.ch>
Sat, 21 Aug 2010 08:46:41 +0000 (10:46 +0200)
Based on patch by Geert Jordaens, fixes bug 571264.

codegen/valaccodebasemodule.vala

index f69cb92d1bf1232ab2f5af50f045e112c81f6319..bf7703e91ff6d5a2bfe290650dd74cd68f7830a1 100644 (file)
@@ -2764,7 +2764,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
                return destroy_func;
        }
 
-       protected string generate_destroy_func_wrapper (DataType type) {
+       protected string generate_free_func_wrapper (DataType type) {
                string destroy_func = "_vala_%s_free".printf (type.data_type.get_cname ());
 
                if (!add_wrapper (destroy_func)) {
@@ -2789,10 +2789,28 @@ public class Vala.CCodeBaseModule : CodeGenerator {
                        free_call.add_argument (new CCodeIdentifier ("self"));
 
                        block.add_statement (new CCodeExpressionStatement (free_call));
-               } else {
+               } else if (cl != null) {
+                       assert (cl.free_function_address_of);
+
                        var free_call = new CCodeFunctionCall (new CCodeIdentifier (type.data_type.get_free_function ()));
                        free_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("self")));
 
+                       block.add_statement (new CCodeExpressionStatement (free_call));
+               } else {
+                       var st = type.data_type as Struct;
+                       if (st != null && st.is_disposable ()) {
+                               if (!st.has_destroy_function) {
+                                       generate_struct_destroy_function (st);
+                               }
+
+                               var destroy_call = new CCodeFunctionCall (new CCodeIdentifier (st.get_destroy_function ()));
+                               destroy_call.add_argument (new CCodeIdentifier ("self"));
+                               block.add_statement (new CCodeExpressionStatement (destroy_call));
+                       }
+
+                       var free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free"));
+                       free_call.add_argument (new CCodeIdentifier ("self"));
+
                        block.add_statement (new CCodeExpressionStatement (free_call));
                }
 
@@ -2839,7 +2857,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
                                } else {
                                        var cl = type.data_type as Class;
                                        if (cl != null && (cl.free_function_address_of || cl.is_gboxed)) {
-                                               unref_function = generate_destroy_func_wrapper (type);
+                                               unref_function = generate_free_func_wrapper (type);
                                        } else {
                                                unref_function = type.data_type.get_free_function ();
                                        }
@@ -2848,7 +2866,11 @@ public class Vala.CCodeBaseModule : CodeGenerator {
                                if (type.nullable) {
                                        unref_function = type.data_type.get_free_function ();
                                        if (unref_function == null) {
-                                               unref_function = "g_free";
+                                               if (type.data_type is Struct && ((Struct) type.data_type).is_disposable ()) {
+                                                       unref_function = generate_free_func_wrapper (type);
+                                               } else {
+                                                       unref_function = "g_free";
+                                               }
                                        }
                                } else {
                                        var st = (Struct) type.data_type;