diff --git a/CHANGES.current b/CHANGES.current index 00d1bec5b..510ec0dfe 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release. Version 2.0.1 (in progress) =========================== +2010-07-08: wsfulton + Fix #3024875 - shared_ptr of classes with non-public destructors. This also fixes + the "unref" feature when used on classes with non-public destructors. + 2010-06-10: wsfulton [Lua] Fix SWIG_lua_isnilstring multiply defined when using multiple modules and wrapping strings. Patch from 'Number Cruncher'. diff --git a/Examples/test-suite/csharp/li_boost_shared_ptr_bits_runme.cs b/Examples/test-suite/csharp/li_boost_shared_ptr_bits_runme.cs index 2b8c84e1b..b4ec47f02 100644 --- a/Examples/test-suite/csharp/li_boost_shared_ptr_bits_runme.cs +++ b/Examples/test-suite/csharp/li_boost_shared_ptr_bits_runme.cs @@ -13,5 +13,8 @@ public class runme int sum = li_boost_shared_ptr_bits.sum(v); if (sum != 66) throw new ApplicationException("sum is wrong"); + + HiddenDestructor hidden = HiddenDestructor.create(); + hidden.Dispose(); } } diff --git a/Examples/test-suite/java/li_boost_shared_ptr_bits_runme.java b/Examples/test-suite/java/li_boost_shared_ptr_bits_runme.java index ffa0c5e64..d1489edf4 100644 --- a/Examples/test-suite/java/li_boost_shared_ptr_bits_runme.java +++ b/Examples/test-suite/java/li_boost_shared_ptr_bits_runme.java @@ -20,5 +20,8 @@ public class li_boost_shared_ptr_bits_runme { int sum = li_boost_shared_ptr_bits.sum(v); if (sum != 66) throw new RuntimeException("sum is wrong"); + + HiddenDestructor hidden = HiddenDestructor.create(); + hidden.delete(); } } diff --git a/Examples/test-suite/li_boost_shared_ptr_bits.i b/Examples/test-suite/li_boost_shared_ptr_bits.i index b43e1b137..7d6fa7b63 100644 --- a/Examples/test-suite/li_boost_shared_ptr_bits.i +++ b/Examples/test-suite/li_boost_shared_ptr_bits.i @@ -48,3 +48,81 @@ int sum(std::vector< boost::shared_ptr > v) { %template(VectorIntHolder) std::vector< boost::shared_ptr >; + +///////////////////////////////////////////////// +// Test non public destructor - was leading to memory leaks as the destructor was not wrapped +// Bug 3024875 +///////////////////////////////////////////////// + +%shared_ptr(HiddenDestructor) + +%inline %{ +class HiddenDestructor; +typedef boost::shared_ptr< HiddenDestructor > FooPtr; + +class HiddenDestructor { +public: + static FooPtr create(); + virtual void doit(); + +protected: + HiddenDestructor(); + static void Foo_body( FooPtr self ); + virtual ~HiddenDestructor(); +private: + HiddenDestructor( const HiddenDestructor& ); + class Impl; + Impl* impl_; + + class FooDeleter { + public: + void operator()(HiddenDestructor* hidden) { + delete hidden; + } + }; +}; +%} + +%{ +#include +using namespace std; + +/* Impl would generally hold a weak_ptr to HiddenDestructor a.s.o, but this stripped down example should suffice */ +class HiddenDestructor::Impl { +public: + int mymember; +}; + +FooPtr HiddenDestructor::create() +{ + FooPtr hidden( new HiddenDestructor(), HiddenDestructor::FooDeleter() ); + Foo_body( hidden ); + return hidden; +} + +void HiddenDestructor::doit() +{ + // whatever +} + +HiddenDestructor::HiddenDestructor() +{ +// cout << "HiddenDestructor::HiddenDestructor()" << endl; + // always empty +} + +void HiddenDestructor::Foo_body( FooPtr self ) +{ + // init self as you would do in ctor + self->impl_ = new Impl(); +} + +HiddenDestructor::~HiddenDestructor() +{ +// cout << "HiddenDestructor::~HiddenDestructor()" << endl; + // destruct (e.g. delete Pimpl object) + delete impl_; +} +%} +//////////////////////////// + diff --git a/Examples/test-suite/python/li_boost_shared_ptr_bits_runme.py b/Examples/test-suite/python/li_boost_shared_ptr_bits_runme.py index 9e5668e57..931317615 100644 --- a/Examples/test-suite/python/li_boost_shared_ptr_bits_runme.py +++ b/Examples/test-suite/python/li_boost_shared_ptr_bits_runme.py @@ -29,3 +29,6 @@ sum = sum(v) if sum != 66: raise "sum is wrong" +################################ +p = HiddenDestructor.create() + diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index f5055ae4b..e28fcbb89 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -2697,7 +2697,7 @@ int Language::destructorDeclaration(Node *n) { if (!CurrentClass) return SWIG_NOWRAP; - if (cplus_mode != PUBLIC) + if (cplus_mode != PUBLIC && !Getattr(CurrentClass, "feature:unref")) return SWIG_NOWRAP; if (ImportMode) return SWIG_NOWRAP;