[glibmm] OptionGroup: Fix build error, remove memory leak.



commit 2622421a587bcb332e41ab5aa51e531a1f8ab6ad
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Thu Feb 17 11:11:57 2011 +0100

    OptionGroup: Fix build error, remove memory leak.
    
    * glib/src/optiongroup.ccg: Fix build error with --enable-warnings=fatal.
    Remove memory leak when the same OptionEntry is added twice.
    Bug #589197 (Hubert Figuiere)

 ChangeLog                |    8 ++++++++
 glib/src/optiongroup.ccg |   31 +++++++++++++++++++++++++++++--
 2 files changed, 37 insertions(+), 2 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 8d46344..c1efa35 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2011-02-17  Kjell Ahlstedt  <kjell ahlstedt bredband net>
+
+	OptionGroup: Fix build error, remove memory leak.
+
+	* glib/src/optiongroup.ccg: Fix build error with --enable-warnings=fatal.
+	Remove memory leak when the same OptionEntry is added twice.
+	Bug #589197 (Hubert Figuiere)
+
 2011-02-16  Murray Cumming  <murrayc murrayc com>
 
 	Move the DBus classes into a Gio::DBus namespace.
diff --git a/glib/src/optiongroup.ccg b/glib/src/optiongroup.ccg
index dfa9d0e..c62af7b 100644
--- a/glib/src/optiongroup.ccg
+++ b/glib/src/optiongroup.ccg
@@ -400,6 +400,13 @@ void OptionGroup::add_entry_with_wrapper(const OptionEntry& entry, GOptionArg ar
 
     add_entry(*(cppEntry.entry_));
   }
+  else if( arg_type == G_OPTION_ARG_CALLBACK )
+  {
+    //Delete the OptionArgCallback instance that was allocated by add_entry()
+    //or add_entry_filename().
+    OptionArgCallback* option_arg = static_cast<OptionArgCallback*>(cpp_arg);
+    delete option_arg;
+  }
 }
 
 
@@ -488,8 +495,28 @@ void OptionGroup::CppOptionEntry::allocate_c_arg()
     }
     case G_OPTION_ARG_CALLBACK:
     {
-      //The C arg pointer is a function pointer.
-      carg_ = reinterpret_cast<void*>(&OptionGroup::option_arg_callback);
+      //The C arg pointer is a function pointer, cast to void*.
+      union {
+        void* dp;
+        GOptionArgFunc fp;
+      } u;
+      u.fp = &OptionGroup::option_arg_callback;
+      carg_ = u.dp;
+
+      // With all compiler warnings turned on and a high optimization level
+      // it's difficult to cast a function pointer to a void*. See bug 589197.
+      // A few results with g++ 4.4.5 with the flags -pedantic -O2 -Werror:
+      //
+      // carg_ = reinterpret_cast<void*>(&OptionGroup::option_arg_callback);
+      // error: ISO C++ forbids casting between pointer-to-function and pointer-to-object
+      //
+      // *reinterpret_cast<GOptionArgFunc*>(&carg_) = &OptionGroup::option_arg_callback;
+      // *(OptionArgFunc*)&carg_ = &OptionGroup::option_arg_callback;
+      // error: dereferencing type-punned pointer will break strict-aliasing rules
+      //
+      // If any compiler dislikes the union, the following code is worth testing:
+      // carg_ = reinterpret_cast<void*>(
+      //         reinterpret_cast<unsigned long>(&OptionGroup::option_arg_callback));
 
       break;
     }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]