From dbf44fc181b880039c20ba8dd3064e3ae7ee0e97 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 6 Mar 2014 19:42:57 +0000 Subject: [PATCH] Fix std::map and smart pointers. Fixes problem with method overloading when some methods are added by %extend and others are real methods and using template default parameters with smart pointers. This is noticeable as a regression since 2.0.12 when using the default smart pointer handling for some languages when the smart pointer wraps std::map and other STL containers. Fixes SF Bug 1363 --- CHANGES.current | 6 ++ Examples/test-suite/common.mk | 1 + ...smart_pointer_template_defaults_overload.i | 56 +++++++++++++++++++ Source/Modules/allocate.cxx | 4 +- Source/Modules/lang.cxx | 6 +- Source/Swig/cwrap.c | 4 +- 6 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 Examples/test-suite/smart_pointer_template_defaults_overload.i diff --git a/CHANGES.current b/CHANGES.current index 8e388dee5..529680e7c 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,12 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.0 (in progress) ============================ +2014-03-06: wsfulton + Fix SF Bug #1363 - Problem with method overloading when some methods are added by %extend + and others are real methods and using template default parameters with smart pointers. + This is noticeable as a regression since 2.0.12 when using the default smart pointer + handling for some languages when the smart pointer wraps std::map and other STL containers. + 2014-03-02: wsfulton [Python] SF Patch #346 from Jens Krueger. Correct exception thrown attempting to access a non-existent C/C++ global variable on the 'cvar' object. The exception thrown diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index b9239315a..e5b61d757 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -347,6 +347,7 @@ CPP_TEST_CASES += \ smart_pointer_simple \ smart_pointer_static \ smart_pointer_template_const_overload \ + smart_pointer_template_defaults_overload \ smart_pointer_templatemethods \ smart_pointer_templatevariables \ smart_pointer_typedef \ diff --git a/Examples/test-suite/smart_pointer_template_defaults_overload.i b/Examples/test-suite/smart_pointer_template_defaults_overload.i new file mode 100644 index 000000000..a1f559ae8 --- /dev/null +++ b/Examples/test-suite/smart_pointer_template_defaults_overload.i @@ -0,0 +1,56 @@ +%module smart_pointer_template_defaults_overload + +// SF Bug #1363 +// Problem with method overloading when some methods are added by %extend and others are real methods +// and using template default parameters with smart pointers. + +%warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED) Wrap::operator->; +%warnfilter(SWIGWARN_LANG_OVERLOAD_SHADOW) Container::rubout; + +%include +%include + +%inline %{ +template +class Wrap { +T *ptr; +public: + Wrap(T *p) : ptr(p) {} + T const* operator->(void) const { return ptr; } + T* operator->(void) { return ptr; } +}; +%} + +%template(StringDoubleMap) std::map; // erase is generated okay +%template(WrappedMap) Wrap< std::map >; // erase wrappers lead to compile error + +// Above only affects some languages depending on how std::map is implemented. +// Below is a cutdown language independent demonstration of the bug + +%extend Container { + void rubout(int, int) {} +} + +%inline %{ +template class Container { +public: + int rubout() { return 0; } + void rubout(T const &element) {} + static Container* factory() { return new Container(); } + static Container* factory(bool b) { return new Container(); } + static void staticstuff(bool) {} +#ifdef SWIG + %extend { + void rubout(bool) {} + } +#endif +}; +%} + +%extend Container { + void rubout(int) {} +} + +%template(ContainerInt) Container; +%template(WrapContainerInt) Wrap< Container >; + diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx index d3384e1ba..d3618634b 100644 --- a/Source/Modules/allocate.cxx +++ b/Source/Modules/allocate.cxx @@ -421,7 +421,7 @@ class Allocate:public Dispatcher { while (cc) { Node *cp = cc; if (classname) { - Setattr(cp, "classname", classname); + Setattr(cp, "extendsmartclassname", classname); } Setattr(cp, "allocate:smartpointeraccess", "1"); /* If constant, we have to be careful */ @@ -827,7 +827,7 @@ Allocate(): } List *methods = smart_pointer_methods(sc, 0, isconst); Setattr(inclass, "allocate:smartpointer", methods); - Setattr(inclass, "allocate:smartpointerbase", base); + Setattr(inclass, "allocate:smartpointerpointeeclassname", Getattr(sc, "name")); } else { /* Hmmm. The return value is not a pointer. If the type is a value or reference. We're going to chase it to see if another operator->() diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 04304744c..a7b088f00 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -1242,8 +1242,8 @@ int Language::memberfunctionHandler(Node *n) { String *fname = Swig_name_member(NSpace, ClassPrefix, symname); if (Extend && SmartPointer) { - if (!Getattr(n, "classname")) { - Setattr(n, "classname", Getattr(CurrentClass, "allocate:smartpointerbase")); + if (!Getattr(n, "extendsmartclassname")) { + Setattr(n, "extendsmartclassname", Getattr(CurrentClass, "allocate:smartpointerpointeeclassname")); } } // Set up the type for the cast to this class for use when wrapping const director (virtual) methods. @@ -1562,7 +1562,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 ? (isNonVirtualProtectedAccess(n) ? DirectorClassName : ClassName) : Getattr(CurrentClass, "allocate:smartpointerbase"); + String *classname = !SmartPointer ? (isNonVirtualProtectedAccess(n) ? DirectorClassName : ClassName) : Getattr(CurrentClass, "allocate:smartpointerpointeeclassname"); if (!value || !Getattr(n, "hasconsttype")) { String *name = Getattr(n, "name"); diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c index 04845f3cf..27eef0ef0 100644 --- a/Source/Swig/cwrap.c +++ b/Source/Swig/cwrap.c @@ -941,7 +941,7 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas is_smart_pointer_overload = 1; } else if (Swig_storage_isstatic(n)) { - String *cname = Getattr(n, "classname") ? Getattr(n, "classname") : classname; + String *cname = Getattr(n, "extendsmartclassname") ? Getattr(n, "extendsmartclassname") : classname; String *ctname = SwigType_namestr(cname); self = NewStringf("(*(%s const *)this)->", ctname); is_smart_pointer_overload = 1; @@ -1058,7 +1058,7 @@ int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *clas String *defaultargs = Getattr(n, "defaultargs"); String *code = Getattr(n, "code"); - String *cname = Getattr(n, "classname") ? Getattr(n, "classname") : classname; + String *cname = Getattr(n, "extendsmartclassname") ? Getattr(n, "extendsmartclassname") : classname; String *membername = Swig_name_member(nspace, cname, name); String *mangled = Swig_name_mangle(membername); int is_smart_pointer = flags & CWRAP_SMART_POINTER;