Skip to content

Commit 24f974b

Browse files
committed
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
1 parent f9efe5b commit 24f974b

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
%module cpp11_shared_ptr_template_upcast
2+
3+
%{
4+
#include <memory>
5+
#include <string>
6+
%}
7+
8+
%include <std_shared_ptr.i>
9+
%include <std_string.i>
10+
11+
%{
12+
class Base {
13+
public:
14+
Base() : value(0) {}
15+
Base(int v) : value(v) {}
16+
virtual ~Base() {}
17+
18+
virtual int GetResult() = 0;
19+
20+
int value;
21+
};
22+
23+
class Derived : public Base {
24+
public:
25+
Derived() : Base() {}
26+
Derived(int v) : Base(v) {}
27+
virtual ~Derived() {}
28+
29+
int GetResult() { return value*2; }
30+
};
31+
32+
template <class T> class Printable : virtual public T {
33+
public:
34+
Printable(int param) : T(param) {}
35+
~Printable() {}
36+
37+
std::string GetFormatted() { return std::string("The formatted result is: ").append(std::to_string(this->GetResult())); }
38+
};
39+
40+
std::shared_ptr<Printable<Derived> > MakePrintableDerived(int param) {
41+
return std::make_shared<Printable<Derived> >(param);
42+
}
43+
44+
%}
45+
46+
%shared_ptr(Base);
47+
%shared_ptr(Derived);
48+
%shared_ptr(Printable<Derived>)
49+
50+
class Base {
51+
public:
52+
Base();
53+
Base(int v);
54+
virtual ~Base();
55+
56+
virtual int GetResult() = 0;
57+
58+
int value;
59+
};
60+
61+
class Derived : public Base {
62+
public:
63+
Derived();
64+
Derived(int v);
65+
virtual ~Derived();
66+
67+
int GetResult();
68+
};
69+
70+
/*
71+
Contrived for this case (but valid for others, such as if Printable was to be a interface/abstract base class).
72+
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
73+
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> >.
74+
*/
75+
template <class T> class Printable : virtual public T {
76+
public:
77+
Printable(int param);
78+
~Printable();
79+
80+
std::string GetFormatted();
81+
};
82+
83+
std::shared_ptr<Printable<Derived> > MakePrintableDerived(int param);
84+
85+
86+
%template(PrintableDerived) Printable<Derived>;
87+
88+

Examples/test-suite/java/Makefile.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ CPP11_TEST_CASES = \
5252
cpp11_shared_ptr_const \
5353
cpp11_shared_ptr_nullptr_in_containers \
5454
cpp11_shared_ptr_overload \
55+
cpp11_shared_ptr_template_upcast \
5556
cpp11_shared_ptr_upcast \
5657
cpp11_std_unordered_map \
5758
cpp11_std_unordered_set \
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
// 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.
3+
// In this case, the expected behavior is that given a cptr (underlying type shared_ptr<Printable<Derived> >), PrintableDerived_SWIGSmartPtrUpcast returns a cptr
4+
// (underlying type std::shared_ptr< Derived >).
5+
6+
import cpp11_shared_ptr_template_upcast.*;
7+
8+
public class cpp11_shared_ptr_template_upcast_runme {
9+
10+
static {
11+
try {
12+
System.loadLibrary("cpp11_shared_ptr_template_upcast");
13+
} catch (UnsatisfiedLinkError e) {
14+
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);
15+
System.exit(1);
16+
}
17+
}
18+
19+
public static void main(String argv[]) {
20+
PrintableDerived pd = cpp11_shared_ptr_template_upcast.MakePrintableDerived(20);
21+
pd.GetResult();
22+
pd.GetFormatted();
23+
}
24+
}
25+

0 commit comments

Comments
 (0)