diff --git a/CHANGES.current b/CHANGES.current index 63dd22d21..5bec5d4e0 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,3 +5,15 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.7 (in progress) =========================== +2015-07-07: wsfulton + SWIG no longer generates a wrapper for a class' constructor if that class has + any base class with a private destructor. This is because your compiler should + not allow a class to be instantiated if a base has a private destructor. Some + compilers do, so if you need the old behaviour, use the "notabstract" feature, eg: + + %feature("notabstract") Derived; + class Base { + ~Base() {} + }; + struct Derived : Base {}; + diff --git a/Examples/test-suite/csharp/default_constructor_runme.cs b/Examples/test-suite/csharp/default_constructor_runme.cs index acd62dc3d..9fc8d754b 100644 --- a/Examples/test-suite/csharp/default_constructor_runme.cs +++ b/Examples/test-suite/csharp/default_constructor_runme.cs @@ -12,13 +12,5 @@ public class runme throw new Exception("Protected destructor exception should have been thrown"); } catch (MethodAccessException) { } - - // calling private destructor test - try { - using (FFF f = new FFF()) { - } - throw new Exception("Private destructor exception should have been thrown"); - } catch (MethodAccessException) { - } } } diff --git a/Examples/test-suite/d/default_constructor_runme.1.d b/Examples/test-suite/d/default_constructor_runme.1.d index 3640218ae..bd79cdf99 100644 --- a/Examples/test-suite/d/default_constructor_runme.1.d +++ b/Examples/test-suite/d/default_constructor_runme.1.d @@ -1,6 +1,5 @@ module default_constructor_runme; -import default_constructor.FFF; import default_constructor.G; void main() { @@ -15,16 +14,4 @@ void main() { throw e; } } - - // Private destructor test. - try { - { - scope f = new FFF(); - } - throw new Exception("Private destructor exception should have been thrown"); - } catch (Exception e) { - if (e.msg != "C++ destructor does not have public access") { - throw e; - } - } } diff --git a/Examples/test-suite/d/default_constructor_runme.2.d b/Examples/test-suite/d/default_constructor_runme.2.d index 22f5bffd2..991b4186a 100644 --- a/Examples/test-suite/d/default_constructor_runme.2.d +++ b/Examples/test-suite/d/default_constructor_runme.2.d @@ -1,6 +1,5 @@ module default_constructor_runme; -import default_constructor.FFF; import default_constructor.G; void main() { @@ -8,7 +7,6 @@ void main() { // destruction yet. // enforceThrows((){ scope g = new G(); }, "Protected destructor exception should have been thrown"); - // enforceThrows((){ scope f = new FFF(); }, "Private destructor exception should have been thrown"); } private void enforceThrows(void delegate() dg, string errorMessage) { diff --git a/Examples/test-suite/default_constructor.i b/Examples/test-suite/default_constructor.i index f7fc8cfa6..74673b74a 100644 --- a/Examples/test-suite/default_constructor.i +++ b/Examples/test-suite/default_constructor.i @@ -13,6 +13,16 @@ SWIGWARN_D_MULTIPLE_INHERITANCE, SWIGWARN_PHP_MULTIPLE_INHERITANCE) AD; /* C#, D, Java, PHP multiple inheritance */ +%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, + SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) GGG; /* C#, D, Java, PHP multiple inheritance */ + +%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, + SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) HHH; /* C#, D, Java, PHP multiple inheritance */ + %warnfilter(SWIGWARN_LANG_FRIEND_IGNORE) F; /* friend function */ %delobject F::destroy; @@ -103,14 +113,15 @@ public: void bar(F *) { } -#if defined(_MSC_VER) - #pragma warning(disable: 4624) // : destructor could not be generated because a base class destructor is inaccessible -#endif +// Single inheritance, base has private destructor class FFF : public F { }; -#if defined(_MSC_VER) - #pragma warning(default: 4624) // : destructor could not be generated because a base class destructor is inaccessible -#endif + +// Multiple inheritance, one base has private destructor +class GGG : public A, public F { +}; +class HHH : public F, public A { +}; /* A class with a protected destructor */ class G { diff --git a/Examples/test-suite/go/default_constructor_runme.go b/Examples/test-suite/go/default_constructor_runme.go index e5e325475..40a5a6e49 100644 --- a/Examples/test-suite/go/default_constructor_runme.go +++ b/Examples/test-suite/go/default_constructor_runme.go @@ -21,9 +21,6 @@ func main() { f := dc.NewF() f.Destroy() - ff := dc.NewFFF() - ff.Destroy() - g := dc.NewG() dc.GDestroy(g) diff --git a/Examples/test-suite/java/default_constructor_runme.java b/Examples/test-suite/java/default_constructor_runme.java index 6473c4099..eb6a2df53 100644 --- a/Examples/test-suite/java/default_constructor_runme.java +++ b/Examples/test-suite/java/default_constructor_runme.java @@ -20,13 +20,5 @@ public class default_constructor_runme { throw new RuntimeException("Protected destructor exception should have been thrown"); } catch (UnsupportedOperationException e) { } - - // calling private destructor test - try { - FFF f = new FFF(); - f.delete(); - throw new RuntimeException("Private destructor exception should have been thrown"); - } catch (UnsupportedOperationException e) { - } } } diff --git a/Examples/test-suite/octave/default_constructor_runme.m b/Examples/test-suite/octave/default_constructor_runme.m index 41d0f3f1e..2f8bb39ef 100644 --- a/Examples/test-suite/octave/default_constructor_runme.m +++ b/Examples/test-suite/octave/default_constructor_runme.m @@ -83,15 +83,6 @@ end_try_catch dc.F_destroy(f); -ff = dc.new_FFF(); -try - del_ff = dc.delete_FFF; - error("Whoa. delete_FFF created") -catch -end_try_catch - -dc.F_destroy(ff); - g = dc.new_G(); try diff --git a/Examples/test-suite/python/default_constructor_runme.py b/Examples/test-suite/python/default_constructor_runme.py index c80c1e81e..1e877adda 100644 --- a/Examples/test-suite/python/default_constructor_runme.py +++ b/Examples/test-suite/python/default_constructor_runme.py @@ -89,15 +89,6 @@ except AttributeError: dc.F_destroy(f) -ff = dc.new_FFF() -try: - del_ff = dc.delete_FFF - print "Whoa. delete_FFF created" -except AttributeError: - pass - -dc.F_destroy(ff) - g = dc.new_G() try: diff --git a/Examples/test-suite/ruby/default_constructor_runme.rb b/Examples/test-suite/ruby/default_constructor_runme.rb index 2706f67ca..5cd675879 100644 --- a/Examples/test-suite/ruby/default_constructor_runme.rb +++ b/Examples/test-suite/ruby/default_constructor_runme.rb @@ -143,9 +143,6 @@ end # This should work fine f = F.new -# This should work fine -ff = FFF.new - # This should work fine g = G.new diff --git a/Examples/test-suite/scilab/default_constructor_runme.sci b/Examples/test-suite/scilab/default_constructor_runme.sci index 6c5250bec..26726f1e0 100644 --- a/Examples/test-suite/scilab/default_constructor_runme.sci +++ b/Examples/test-suite/scilab/default_constructor_runme.sci @@ -84,15 +84,6 @@ end F_destroy(f); -ff = new_FFF(); -try - del_ff = delete_FFF; - swigtesterror("delete_FFF created") -catch -end - -F_destroy(ff); - g = new_G(); try diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx index dc3820766..f79373d18 100644 --- a/Source/Modules/allocate.cxx +++ b/Source/Modules/allocate.cxx @@ -941,6 +941,8 @@ Allocate(): Setattr(inclass, "allocate:default_destructor", "1"); } else if (cplus_mode == PROTECTED) { Setattr(inclass, "allocate:default_base_destructor", "1"); + } else if (cplus_mode == PRIVATE) { + Setattr(inclass, "allocate:private_destructor", "1"); } } else { Setattr(inclass, "allocate:has_destructor", "1"); diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 7943dc4c7..aa81581f0 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -3676,14 +3676,26 @@ int Language::abstractClassTest(Node *n) { return 0; if (Getattr(n, "allocate:nonew")) return 1; + + // A class cannot be instantiated if one of its bases has a private destructor + // Note that if the above does not hold the class can be instantiated if its own destructor is private + List *bases = Getattr(n, "bases"); + if (bases) { + for (int i = 0; i < Len(bases); i++) { + Node *b = Getitem(bases, i); + if (GetFlag(b, "allocate:private_destructor")) + return 1; + } + } + /* now check for the rest */ List *abstracts = Getattr(n, "abstracts"); if (!abstracts) return 0; int labs = Len(abstracts); #ifdef SWIG_DEBUG - List *bases = Getattr(n, "allbases"); - Printf(stderr, "testing %s %d %d\n", Getattr(n, "name"), labs, Len(bases)); + List *allbases = Getattr(n, "allbases"); + Printf(stderr, "testing %s %d %d\n", Getattr(n, "name"), labs, Len(allbases)); #endif if (!labs) return 0; /*strange, but need to be fixed */