Fix bug 3529601 - seg fault when a protected method has the director

feature but the parent class does not. Also fix similar problems with
the allprotected feature.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@13135 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2012-05-29 22:02:43 +00:00
parent 5b2f38101f
commit 7ec1e11604
6 changed files with 58 additions and 11 deletions

View File

@ -4,6 +4,11 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.8 (in progress)
===========================
2012-05-29: wsfulton
Fix #3529601 - seg fault when a protected method has the "director"
feature but the parent class does not. Also fix similar problems with
the allprotected feature.
2012-05-28: wsfulton
Fix seg fault when attempting to warn about an illegal destructor - #3530055, 3530078 and #3530118.

View File

@ -0,0 +1,27 @@
// Tests directors and allprotected option when the class does not have the "director" feature
// Was previously crashing and/or generating uncompilable code.
%module(directors="1", allprotected="1") allprotected_not
//%feature("director") AllProtectedNot;
%feature("director") AllProtectedNot::ProtectedMethod;
%feature("director") AllProtectedNot::StaticNonVirtualProtectedMethod;
%feature("director") AllProtectedNot::NonVirtualProtectedMethod;
%feature("director") AllProtectedNot::ProtectedVariable;
%feature("director") AllProtectedNot::StaticProtectedVariable;
%feature("director") AllProtectedNot::PublicMethod;
%inline %{
class AllProtectedNot {
public:
virtual ~AllProtectedNot() {}
virtual void PublicMethod() {}
protected:
virtual void ProtectedMethod() {}
static void StaticNonVirtualProtectedMethod() {}
void NonVirtualProtectedMethod() {}
int ProtectedVariable;
static int StaticProtectedVariable;
};
int AllProtectedNot::StaticProtectedVariable = 0;
%}

View File

@ -108,6 +108,7 @@ CPP_TEST_CASES += \
aggregate \
allowexcept \
allprotected \
allprotected_not \
anonymous_bitfield \
apply_signed_char \
apply_strings \

View File

@ -2088,7 +2088,7 @@ private:
}
int flags = Extend | SmartPointer | use_naturalvar_mode(var);
if (is_non_virtual_protected_access(var)) {
if (isNonVirtualProtectedAccess(var)) {
flags |= CWRAP_ALL_PROTECTED_ACCESS;
}

View File

@ -841,7 +841,7 @@ int Language::cDeclaration(Node *n) {
if (!isfriend) {
/* Check what the director needs. If the method is pure virtual, it is always needed.
* Also wrap non-virtual protected members if asked for (allprotected mode). */
if (!(directorsEnabled() && ((is_member_director(CurrentClass, n) && need_nonpublic_member(n)) || is_non_virtual_protected_access(n)))) {
if (!(directorsEnabled() && ((is_member_director(CurrentClass, n) && need_nonpublic_member(n)) || isNonVirtualProtectedAccess(n)))) {
return SWIG_NOWRAP;
}
// Prevent wrapping protected overloaded director methods more than once -
@ -1224,7 +1224,7 @@ int Language::memberfunctionHandler(Node *n) {
// Set up the type for the cast to this class for use when wrapping const director (virtual) methods.
// Note: protected director methods or when allprotected mode turned on.
String *director_type = 0;
if (!is_public(n) && (is_member_director(CurrentClass, n) || GetFlag(n, "explicitcall") || is_non_virtual_protected_access(n))) {
if (!is_public(n) && (is_member_director(CurrentClass, n) || GetFlag(n, "explicitcall") || isNonVirtualProtectedAccess(n))) {
director_type = Copy(DirectorClassName);
String *qualifier = Getattr(n, "qualifier");
if (qualifier)
@ -1270,7 +1270,7 @@ int Language::staticmemberfunctionHandler(Node *n) {
if (!Extend) {
Node *sb = Getattr(n, "cplus:staticbase");
String *sname = Getattr(sb, "name");
if (is_non_virtual_protected_access(n))
if (isNonVirtualProtectedAccess(n))
cname = NewStringf("%s::%s", DirectorClassName, name);
else
cname = NewStringf("%s::%s", sname, name);
@ -1415,14 +1415,14 @@ int Language::membervariableHandler(Node *n) {
Delete(pname);
}
} else {
String *pname = is_non_virtual_protected_access(n) ? NewString("darg") : Swig_cparm_name(0, 0);
String *pname = isNonVirtualProtectedAccess(n) ? NewString("darg") : Swig_cparm_name(0, 0);
target = NewStringf("%s->%s", pname, name);
Delete(pname);
}
tm = Swig_typemap_lookup("memberin", n, target, 0);
}
int flags = Extend | SmartPointer | use_naturalvar_mode(n);
if (is_non_virtual_protected_access(n))
if (isNonVirtualProtectedAccess(n))
flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
Swig_MembersetToFunction(n, ClassType, flags);
@ -1470,7 +1470,7 @@ int Language::membervariableHandler(Node *n) {
/* Emit get function */
{
int flags = Extend | SmartPointer | use_naturalvar_mode(n);
if (is_non_virtual_protected_access(n))
if (isNonVirtualProtectedAccess(n))
flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
Swig_MembergetToFunction(n, ClassType, flags);
Setattr(n, "sym:name", mrename_get);
@ -1530,7 +1530,7 @@ int Language::membervariableHandler(Node *n) {
int Language::staticmembervariableHandler(Node *n) {
Swig_require("staticmembervariableHandler", n, "*name", "*sym:name", "*type", "?value", NIL);
String *value = Getattr(n, "value");
String *classname = !SmartPointer ? (is_non_virtual_protected_access(n) ? DirectorClassName : ClassName) : Getattr(CurrentClass, "allocate:smartpointerbase");
String *classname = !SmartPointer ? (isNonVirtualProtectedAccess(n) ? DirectorClassName : ClassName) : Getattr(CurrentClass, "allocate:smartpointerbase");
if (!value || !Getattr(n, "hasconsttype")) {
String *name = Getattr(n, "name");
@ -1695,7 +1695,7 @@ int Language::memberconstantHandler(Node *n) {
if (Extend)
new_name = Copy(value);
else
new_name = NewStringf("%s::%s", is_non_virtual_protected_access(n) ? DirectorClassName : ClassName, name);
new_name = NewStringf("%s::%s", isNonVirtualProtectedAccess(n) ? DirectorClassName : ClassName, name);
Setattr(n, "name", new_name);
constantWrapper(n);
@ -2116,7 +2116,7 @@ int Language::classDirector(Node *n) {
Node *nodeType = Getattr(ni, "nodeType");
bool cdeclaration = (Cmp(nodeType, "cdecl") == 0);
if (cdeclaration && !GetFlag(ni, "feature:ignore")) {
if (is_non_virtual_protected_access(ni)) {
if (isNonVirtualProtectedAccess(ni)) {
Node *overloaded = Getattr(ni, "sym:overloaded");
// emit the using base::member statement (but only once if the method is overloaded)
if (!overloaded || (overloaded && (overloaded == ni)))
@ -3331,7 +3331,7 @@ int Language::need_nonpublic_ctor(Node *n) {
* Language::need_nonpublic_member()
* ----------------------------------------------------------------------------- */
int Language::need_nonpublic_member(Node *n) {
if (directorsEnabled()) {
if (directorsEnabled() && DirectorClassName) {
if (is_protected(n)) {
if (dirprot_mode()) {
/* when using dirprot mode, the protected members are always needed. */
@ -3355,6 +3355,16 @@ int Language::is_smart_pointer() const {
return SmartPointer;
}
/* -----------------------------------------------------------------------------
* Language::()
* ----------------------------------------------------------------------------- */
bool Language::isNonVirtualProtectedAccess(Node *n) const {
// Ideally is_non_virtual_protected_access() would contain all this logic, see
// comments therein about vtable.
return DirectorClassName && is_non_virtual_protected_access(n);
}
/* -----------------------------------------------------------------------------
* Language::extraDirectorProtectedCPPMethodsRequired()
* ----------------------------------------------------------------------------- */

View File

@ -294,6 +294,10 @@ protected:
/* Some language modules require additional wrappers for virtual methods not declared in sub-classes */
virtual bool extraDirectorProtectedCPPMethodsRequired() const;
/* Identifies if a protected members that are generated when the allprotected option is used.
This does not include protected virtual methods as they are turned on with the dirprot option. */
bool isNonVirtualProtectedAccess(Node *n) const;
/* Director subclass comparison test */
String *none_comparison;