Adding test case demonstrating issue where SWIG does not generate a correctly typed, upcasted shared_ptr for a template instantiation deriving from a base class

This commit is contained in:
etse 2019-05-01 17:05:44 -04:00
commit 24f974bb0c
3 changed files with 114 additions and 0 deletions

View file

@ -0,0 +1,88 @@
%module cpp11_shared_ptr_template_upcast
%{
#include <memory>
#include <string>
%}
%include <std_shared_ptr.i>
%include <std_string.i>
%{
class Base {
public:
Base() : value(0) {}
Base(int v) : value(v) {}
virtual ~Base() {}
virtual int GetResult() = 0;
int value;
};
class Derived : public Base {
public:
Derived() : Base() {}
Derived(int v) : Base(v) {}
virtual ~Derived() {}
int GetResult() { return value*2; }
};
template <class T> class Printable : virtual public T {
public:
Printable(int param) : T(param) {}
~Printable() {}
std::string GetFormatted() { return std::string("The formatted result is: ").append(std::to_string(this->GetResult())); }
};
std::shared_ptr<Printable<Derived> > MakePrintableDerived(int param) {
return std::make_shared<Printable<Derived> >(param);
}
%}
%shared_ptr(Base);
%shared_ptr(Derived);
%shared_ptr(Printable<Derived>)
class Base {
public:
Base();
Base(int v);
virtual ~Base();
virtual int GetResult() = 0;
int value;
};
class Derived : public Base {
public:
Derived();
Derived(int v);
virtual ~Derived();
int GetResult();
};
/*
Contrived for this case (but valid for others, such as if Printable was to be a interface/abstract base class).
Virtual inheritance exposes whether SWIGSmartPtrUpcast generated a correctly typed shared pointer of the upcasted class type - if the pointer type is incorrect, this will result in
a segmentation fault (on Windows, this could manifest as undefined behavior) when trying to access any member inherited from T through a shared_ptr<Printable<T> >.
*/
template <class T> class Printable : virtual public T {
public:
Printable(int param);
~Printable();
std::string GetFormatted();
};
std::shared_ptr<Printable<Derived> > MakePrintableDerived(int param);
%template(PrintableDerived) Printable<Derived>;

View file

@ -52,6 +52,7 @@ CPP11_TEST_CASES = \
cpp11_shared_ptr_const \
cpp11_shared_ptr_nullptr_in_containers \
cpp11_shared_ptr_overload \
cpp11_shared_ptr_template_upcast \
cpp11_shared_ptr_upcast \
cpp11_std_unordered_map \
cpp11_std_unordered_set \

View file

@ -0,0 +1,25 @@
// This is the cpp11_shared_ptr_template_upcast runtime testcase. It checks that SWIG generates the appropriate, upcasted shared_ptr type for a template instantiation deriving from a base class.
// In this case, the expected behavior is that given a cptr (underlying type shared_ptr<Printable<Derived> >), PrintableDerived_SWIGSmartPtrUpcast returns a cptr
// (underlying type std::shared_ptr< Derived >).
import cpp11_shared_ptr_template_upcast.*;
public class cpp11_shared_ptr_template_upcast_runme {
static {
try {
System.loadLibrary("cpp11_shared_ptr_template_upcast");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[]) {
PrintableDerived pd = cpp11_shared_ptr_template_upcast.MakePrintableDerived(20);
pd.GetResult();
pd.GetFormatted();
}
}