Add warnings for badly named destructors. Fix %extend and destructors for templates - they weren't always being wrapped. Fix destructor "name" attribute.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12804 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2011-09-13 06:15:29 +00:00
commit 4c6f66577a
10 changed files with 226 additions and 28 deletions

View file

@ -4,6 +4,29 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.5 (in progress)
===========================
2011-09-13: wsfulton
Add warnings for badly named destructors, eg:
struct KStruct {
~NOT_KStruct() {}
};
cpp_extend_destructors.i:92: Warning 521: Illegal destructor name ~NOT_KStruct. Ignored.
2011-09-13: wsfulton
Fix %extend and destructors for templates. The destructor in %extend was not always wrapped,
for example:
%extend FooT {
~FooT() { delete $self; } // was not wrapped as expected
};
template<class T> class FooT {};
%template(FooTi) FooT<int>;
2011-09-13: wsfulton
Fix special variables such as "$decl" and "$fulldecl" in destructors to include the ~ character.
2011-09-10: talby
[perl5] SF bug #1481958 - Improve range checking for integer types.
Enhance li_typemaps_runme.pl

View file

@ -501,7 +501,7 @@ example.i(4) : Syntax error in input.
<li>501. Overloaded declaration ignored. <em>decl</em>. Previous declaration is <em>decl</em>.
<li>502. Overloaded constructor ignored. <em>decl</em>. Previous declaration is <em>decl</em>.
<li>503. Can't wrap '<em>identifier</em>' unless renamed to a valid identifier.
<li>504. Function <em>name</em> must have a return type.
<li>504. Function <em>name</em> must have a return type. Ignored.
<li>505. Variable length arguments discarded.
<li>506. Can't wrap varargs with keyword arguments enabled.
<li>507. Adding native function <em>name</em> not supported (ignored).
@ -518,6 +518,7 @@ example.i(4) : Syntax error in input.
<li>518. Portability warning: File <em>file1</em> will be overwritten by <em>file2</em> on case insensitive filesystems such as Windows' FAT32 and NTFS unless the class/module name is renamed.
<li>519. %template() contains no name. Template method ignored: <em>declaration</em>
<li>520. <em>Base/Derived</em> class '<em>classname1</em>' of '<em>classname2</em>' is not similarly marked as a smart pointer.
<li>521. Illegal destructor name <em>name</em>. Ignored.
</ul>
<H3><a name="Warnings_nn15"></a>14.9.6 Language module specific (700-899) </H3>

View file

@ -0,0 +1,104 @@
%module xxx
/////////////////////////////
%extend AStruct {
~AStruct() {}
}
struct AStruct {
~AStruct() {}
};
/////////////////////////////
struct BStruct {
~BStruct() {}
~BStruct() {}
};
/////////////////////////////
struct CStruct {
};
%extend CStruct {
~NOT_CStruct() {
delete $self;
}
}
%extend DStruct {
~NOT_DStruct() {
delete $self;
}
}
struct DStruct {
};
/////////////////////////////
struct EStruct {
~EStruct() {}
};
%extend EStruct {
~NOT_EStruct() {
delete $self;
}
}
%extend FStruct {
~NOT_FStruct() {
delete $self;
}
}
struct FStruct {
~FStruct() {}
};
/////////////////////////////
struct GStruct {
};
%extend GStruct {
~GStruct() {}
~NOT_GStruct() {
delete $self;
}
}
%extend HStruct {
~HStruct() {}
~NOT_HStruct() {
delete $self;
}
}
struct HStruct {
};
/////////////////////////////
struct IStruct {
~IStruct() {}
~NOT_IStruct() {}
};
struct JStruct {
~JStruct() {}
~NOT_JStruct() {}
~JStruct() {}
};
/////////////////////////////
struct KStruct {
~NOT_KStruct() {}
};
/////////////////////////////
template<typename T>
struct LStruct {
~LStruct() {}
~NOT_LStruct() {}
~LStruct() {}
};
%template(LStructInt) LStruct<int>;
%template(LStructShort) LStruct<short>;

View file

@ -209,6 +209,27 @@ Doc/Manual/Typemaps.html for complete details.
cpp_bad_extern.i:5: Warning 313: Unrecognized extern type "INTERCAL".
cpp_bad_extern.i:7: Warning 313: Unrecognized extern type "INTERCAL".
:::::::::::::::::::::::::::::::: cpp_extend_destructors.i :::::::::::::::::::::::::::::::::::
cpp_extend_destructors.i:8: Warning 302: Identifier '~AStruct' redefined by %extend (ignored),
cpp_extend_destructors.i:5: Warning 302: %extend definition of '~AStruct'.
cpp_extend_destructors.i:14: Warning 302: Identifier '~BStruct' redefined (ignored),
cpp_extend_destructors.i:13: Warning 302: previous definition of '~BStruct'.
cpp_extend_destructors.i:87: Warning 302: Identifier '~JStruct' redefined (ignored),
cpp_extend_destructors.i:85: Warning 302: previous definition of '~JStruct'.
cpp_extend_destructors.i:100: Warning 302: Identifier '~LStruct' redefined (ignored),
cpp_extend_destructors.i:98: Warning 302: previous definition of '~LStruct'.
cpp_extend_destructors.i:24: Warning 521: Illegal destructor name ~NOT_CStruct. Ignored.
cpp_extend_destructors.i:30: Warning 521: Illegal destructor name ~NOT_DStruct. Ignored.
cpp_extend_destructors.i:44: Warning 521: Illegal destructor name ~NOT_EStruct. Ignored.
cpp_extend_destructors.i:50: Warning 521: Illegal destructor name ~NOT_FStruct. Ignored.
cpp_extend_destructors.i:65: Warning 521: Illegal destructor name ~NOT_GStruct. Ignored.
cpp_extend_destructors.i:72: Warning 521: Illegal destructor name ~NOT_HStruct. Ignored.
cpp_extend_destructors.i:81: Warning 521: Illegal destructor name ~NOT_IStruct. Ignored.
cpp_extend_destructors.i:86: Warning 521: Illegal destructor name ~NOT_JStruct. Ignored.
cpp_extend_destructors.i:92: Warning 521: Illegal destructor name ~NOT_KStruct. Ignored.
cpp_extend_destructors.i:99: Warning 521: Illegal destructor name ~NOT_LStruct< int >. Ignored.
cpp_extend_destructors.i:99: Warning 521: Illegal destructor name ~NOT_LStruct< short >. Ignored.
:::::::::::::::::::::::::::::::: cpp_extend_redefine.i :::::::::::::::::::::::::::::::::::
cpp_extend_redefine.i:9: Warning 302: Identifier 'bar' redefined by %extend (ignored),
cpp_extend_redefine.i:5: Warning 302: %extend definition of 'bar'.

View file

@ -63,6 +63,7 @@ swig_typemap_old
# Files run in C++ mode
CPPFILES='
cpp_bad_extern
cpp_extend_destructors
cpp_extend_redefine
cpp_extend_undefined
cpp_inline_namespace

View file

@ -20,20 +20,21 @@ namespace Space {
typedef struct {
int ivar;
} DStruct;
}
typedef struct tagEStruct {
int ivar;
} EStruct;
namespace Space {
template<typename T>
struct FFStruct {
int ivar;
};
}
%}
%extend Junk {
void thingy() {}
}
%inline %{
struct Junk {};
%}
namespace Space {
%extend tagAStruct {
@ -103,3 +104,22 @@ namespace Space {
}
}
namespace Space {
%extend FFStruct {
FFStruct(int ivar0) {
Space::FFStruct<T> *s = new Space::FFStruct<T>();
s->ivar = ivar0;
global = ivar0;
return s;
}
~FFStruct() {
global = -$self->ivar;
delete $self;
}
}
}
%template(FStruct) Space::FFStruct<long>;
%template(GStruct) Space::FFStruct<char>;

View file

@ -20,6 +20,12 @@ public class extend_constructor_destructor_runme {
checkGlobal(30);
DStruct d = new DStruct(40);
checkGlobal(40);
EStruct e = new EStruct(50);
checkGlobal(50);
FStruct f = new FStruct(60);
checkGlobal(60);
GStruct g = new GStruct(70);
checkGlobal(70);
a.delete();
checkGlobal(-10);
@ -29,6 +35,12 @@ public class extend_constructor_destructor_runme {
checkGlobal(-30);
d.delete();
checkGlobal(-40);
e.delete();
checkGlobal(-50);
f.delete();
checkGlobal(-60);
g.delete();
checkGlobal(-70);
}
public static void checkGlobal(int val) {

View file

@ -195,6 +195,7 @@
#define WARN_LANG_PORTABILITY_FILENAME 518
#define WARN_LANG_TEMPLATE_METHOD_IGNORE 519
#define WARN_LANG_SMARTPTR_MISSING 520
#define WARN_LANG_ILLEGAL_DESTRUCTOR 521
/* -- Reserved (600-799) -- */

View file

@ -936,6 +936,9 @@ Allocate():
} else if (cplus_mode == PROTECTED) {
Setattr(inclass, "allocate:default_base_destructor", "1");
}
} else {
Setattr(inclass, "allocate:has_destructor", "1");
Setattr(inclass, "allocate:default_destructor", "1");
}
return SWIG_OK;
}

View file

@ -2609,17 +2609,18 @@ int Language::constructorDeclaration(Node *n) {
}
}
} else {
if (name && (!Equal(Swig_scopename_last(name), Swig_scopename_last(ClassName))) && !(Getattr(n, "template"))) {
bool illegal_method = true;
String *expected_name = ClassName;
if (name && (!Equal(Swig_scopename_last(name), Swig_scopename_last(expected_name))) && !(Getattr(n, "template"))) {
bool illegal_name = true;
if (Extend) {
// SWIG extension - allow typedef names as constructor name in %extend - an unnamed struct declared with a typedef can thus be given a 'constructor'.
SwigType *name_resolved = SwigType_typedef_resolve_all(name);
SwigType *classname_resolved = SwigType_typedef_resolve_all(ClassName);
illegal_method = !Equal(name_resolved, classname_resolved);
SwigType *expected_name_resolved = SwigType_typedef_resolve_all(expected_name);
illegal_name = !Equal(name_resolved, expected_name_resolved);
Delete(name_resolved);
Delete(classname_resolved);
Delete(expected_name_resolved);
}
if (illegal_method) {
if (illegal_name) {
Swig_warning(WARN_LANG_RETURN_TYPE, input_file, line_number, "Function %s must have a return type. Ignored.\n", SwigType_namestr(name));
Swig_restore(n);
return SWIG_NOWRAP;
@ -2727,24 +2728,12 @@ int Language::destructorDeclaration(Node *n) {
if (ImportMode)
return SWIG_NOWRAP;
if (Extend) {
/* extend destructor can be safely ignored if there is already one */
if (Getattr(CurrentClass, "has_destructor")) {
return SWIG_NOWRAP;
}
}
Swig_save("destructorDeclaration", n, "name", "sym:name", NIL);
char *c = GetChar(n, "name");
if (c && (*c == '~'))
Setattr(n, "name", c + 1);
c = GetChar(n, "sym:name");
if (c && (*c == '~'))
char *c = GetChar(n, "sym:name");
if (c && (*c == '~')) {
Setattr(n, "sym:name", c + 1);
/* Name adjustment for %name */
}
String *name = Getattr(n, "name");
String *symname = Getattr(n, "sym:name");
@ -2753,10 +2742,33 @@ int Language::destructorDeclaration(Node *n) {
Setattr(n, "sym:name", ClassPrefix);
}
String *expected_name = NewString(ClassName);
Replace(expected_name, "~", "", DOH_REPLACE_FIRST);
String *actual_name = NewString(name);
Replace(actual_name, "~", "", DOH_REPLACE_FIRST);
if (name && (!Equal(Swig_scopename_last(actual_name), Swig_scopename_last(expected_name))) && !(Getattr(n, "template"))) {
bool illegal_name = true;
if (Extend) {
// SWIG extension - allow typedef names as destructor name in %extend - an unnamed struct declared with a typedef can thus be given a 'destructor'.
SwigType *name_resolved = SwigType_typedef_resolve_all(actual_name);
SwigType *expected_name_resolved = SwigType_typedef_resolve_all(expected_name);
illegal_name = !Equal(name_resolved, expected_name_resolved);
Delete(name_resolved);
Delete(expected_name_resolved);
}
if (illegal_name) {
Swig_warning(WARN_LANG_ILLEGAL_DESTRUCTOR, input_file, line_number, "Illegal destructor name %s. Ignored.\n", SwigType_namestr(name));
Swig_restore(n);
Delete(expected_name);
return SWIG_NOWRAP;
}
}
destructorHandler(n);
Setattr(CurrentClass, "has_destructor", "1");
Swig_restore(n);
Delete(expected_name);
return SWIG_OK;
}