Don't generate constructor wrappers if a base class has a private constructor
g++-5 errors out with this now with errors such as:
default_constructor_wrap.cxx:665:27: error: use of deleted function ‘FFF::FFF()’
result = (FFF *)new FFF();
^
default_constructor_wrap.cxx:314:7: note: ‘FFF::FFF()’ is implicitly deleted because the default definition would be ill-formed:
class FFF : public F {
^
default_constructor_wrap.cxx:301:4: error: ‘F::~F()’ is private
~F() { }
^
default_constructor_wrap.cxx:314:7: error: within this context
This commit is contained in:
parent
1514e19efb
commit
3718b810c7
13 changed files with 45 additions and 72 deletions
|
|
@ -5,3 +5,15 @@ See the RELEASENOTES file for a summary of changes in each release.
|
||||||
Version 3.0.7 (in progress)
|
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 {};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,5 @@ public class runme
|
||||||
throw new Exception("Protected destructor exception should have been thrown");
|
throw new Exception("Protected destructor exception should have been thrown");
|
||||||
} catch (MethodAccessException) {
|
} catch (MethodAccessException) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// calling private destructor test
|
|
||||||
try {
|
|
||||||
using (FFF f = new FFF()) {
|
|
||||||
}
|
|
||||||
throw new Exception("Private destructor exception should have been thrown");
|
|
||||||
} catch (MethodAccessException) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
module default_constructor_runme;
|
module default_constructor_runme;
|
||||||
|
|
||||||
import default_constructor.FFF;
|
|
||||||
import default_constructor.G;
|
import default_constructor.G;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
@ -15,16 +14,4 @@ void main() {
|
||||||
throw e;
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
module default_constructor_runme;
|
module default_constructor_runme;
|
||||||
|
|
||||||
import default_constructor.FFF;
|
|
||||||
import default_constructor.G;
|
import default_constructor.G;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
@ -8,7 +7,6 @@ void main() {
|
||||||
// destruction yet.
|
// destruction yet.
|
||||||
|
|
||||||
// enforceThrows((){ scope g = new G(); }, "Protected destructor exception should have been thrown");
|
// 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) {
|
private void enforceThrows(void delegate() dg, string errorMessage) {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,16 @@
|
||||||
SWIGWARN_D_MULTIPLE_INHERITANCE,
|
SWIGWARN_D_MULTIPLE_INHERITANCE,
|
||||||
SWIGWARN_PHP_MULTIPLE_INHERITANCE) AD; /* C#, D, Java, PHP 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 */
|
%warnfilter(SWIGWARN_LANG_FRIEND_IGNORE) F; /* friend function */
|
||||||
|
|
||||||
%delobject F::destroy;
|
%delobject F::destroy;
|
||||||
|
|
@ -103,14 +113,15 @@ public:
|
||||||
|
|
||||||
void bar(F *) { }
|
void bar(F *) { }
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
// Single inheritance, base has private destructor
|
||||||
#pragma warning(disable: 4624) // : destructor could not be generated because a base class destructor is inaccessible
|
|
||||||
#endif
|
|
||||||
class FFF : public F {
|
class FFF : public F {
|
||||||
};
|
};
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#pragma warning(default: 4624) // : destructor could not be generated because a base class destructor is inaccessible
|
// Multiple inheritance, one base has private destructor
|
||||||
#endif
|
class GGG : public A, public F {
|
||||||
|
};
|
||||||
|
class HHH : public F, public A {
|
||||||
|
};
|
||||||
|
|
||||||
/* A class with a protected destructor */
|
/* A class with a protected destructor */
|
||||||
class G {
|
class G {
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,6 @@ func main() {
|
||||||
f := dc.NewF()
|
f := dc.NewF()
|
||||||
f.Destroy()
|
f.Destroy()
|
||||||
|
|
||||||
ff := dc.NewFFF()
|
|
||||||
ff.Destroy()
|
|
||||||
|
|
||||||
g := dc.NewG()
|
g := dc.NewG()
|
||||||
|
|
||||||
dc.GDestroy(g)
|
dc.GDestroy(g)
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,5 @@ public class default_constructor_runme {
|
||||||
throw new RuntimeException("Protected destructor exception should have been thrown");
|
throw new RuntimeException("Protected destructor exception should have been thrown");
|
||||||
} catch (UnsupportedOperationException e) {
|
} 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) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,15 +83,6 @@ end_try_catch
|
||||||
|
|
||||||
dc.F_destroy(f);
|
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();
|
g = dc.new_G();
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -89,15 +89,6 @@ except AttributeError:
|
||||||
|
|
||||||
dc.F_destroy(f)
|
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()
|
g = dc.new_G()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -143,9 +143,6 @@ end
|
||||||
# This should work fine
|
# This should work fine
|
||||||
f = F.new
|
f = F.new
|
||||||
|
|
||||||
# This should work fine
|
|
||||||
ff = FFF.new
|
|
||||||
|
|
||||||
# This should work fine
|
# This should work fine
|
||||||
g = G.new
|
g = G.new
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,15 +84,6 @@ end
|
||||||
|
|
||||||
F_destroy(f);
|
F_destroy(f);
|
||||||
|
|
||||||
ff = new_FFF();
|
|
||||||
try
|
|
||||||
del_ff = delete_FFF;
|
|
||||||
swigtesterror("delete_FFF created")
|
|
||||||
catch
|
|
||||||
end
|
|
||||||
|
|
||||||
F_destroy(ff);
|
|
||||||
|
|
||||||
g = new_G();
|
g = new_G();
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -941,6 +941,8 @@ Allocate():
|
||||||
Setattr(inclass, "allocate:default_destructor", "1");
|
Setattr(inclass, "allocate:default_destructor", "1");
|
||||||
} else if (cplus_mode == PROTECTED) {
|
} else if (cplus_mode == PROTECTED) {
|
||||||
Setattr(inclass, "allocate:default_base_destructor", "1");
|
Setattr(inclass, "allocate:default_base_destructor", "1");
|
||||||
|
} else if (cplus_mode == PRIVATE) {
|
||||||
|
Setattr(inclass, "allocate:private_destructor", "1");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Setattr(inclass, "allocate:has_destructor", "1");
|
Setattr(inclass, "allocate:has_destructor", "1");
|
||||||
|
|
|
||||||
|
|
@ -3676,14 +3676,26 @@ int Language::abstractClassTest(Node *n) {
|
||||||
return 0;
|
return 0;
|
||||||
if (Getattr(n, "allocate:nonew"))
|
if (Getattr(n, "allocate:nonew"))
|
||||||
return 1;
|
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 */
|
/* now check for the rest */
|
||||||
List *abstracts = Getattr(n, "abstracts");
|
List *abstracts = Getattr(n, "abstracts");
|
||||||
if (!abstracts)
|
if (!abstracts)
|
||||||
return 0;
|
return 0;
|
||||||
int labs = Len(abstracts);
|
int labs = Len(abstracts);
|
||||||
#ifdef SWIG_DEBUG
|
#ifdef SWIG_DEBUG
|
||||||
List *bases = Getattr(n, "allbases");
|
List *allbases = Getattr(n, "allbases");
|
||||||
Printf(stderr, "testing %s %d %d\n", Getattr(n, "name"), labs, Len(bases));
|
Printf(stderr, "testing %s %d %d\n", Getattr(n, "name"), labs, Len(allbases));
|
||||||
#endif
|
#endif
|
||||||
if (!labs)
|
if (!labs)
|
||||||
return 0; /*strange, but need to be fixed */
|
return 0; /*strange, but need to be fixed */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue