Skip to content

Commit 6910e5f

Browse files
committed
Merge branch 'shared-ptr-template-upcast'
* shared-ptr-template-upcast: comments Applying shared_ptr template upcast fix to CSharp, adding CSharp test, and cleanup 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 WIP - Use the non-encoded type string for upcasting a shared_ptr of a derived type to a shared_ptr of the base type comments Applying shared_ptr template upcast fix to CSharp, adding CSharp test, and cleanup 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 WIP - Use the non-encoded type string for upcasting a shared_ptr of a derived type to a shared_ptr of the base type
2 parents 7051753 + 50b42f8 commit 6910e5f

File tree

7 files changed

+143
-10
lines changed

7 files changed

+143
-10
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+
Virtual inheritance is contrived for this case, but exposes whether SWIGSmartPtrUpcast generated a correctly typed shared pointer of the upcasted class type -
72+
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 members
73+
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/csharp/Makefile.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ CPP11_TEST_CASES = \
3535
cpp11_shared_ptr_const \
3636
cpp11_shared_ptr_nullptr_in_containers \
3737
cpp11_shared_ptr_overload \
38+
cpp11_shared_ptr_template_upcast \
3839
cpp11_shared_ptr_upcast \
3940
cpp11_strongly_typed_enumerations_simple \
4041

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// 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.
2+
// For this case, the expected behavior is: given a cptr with underlying type shared_ptr<Printable<Derived> >, PrintableDerived_SWIGSmartPtrUpcast returns a cptr with
3+
// underlying type std::shared_ptr< Derived >, where Printable<Derived> inherits from Derived.
4+
using System;
5+
using cpp11_shared_ptr_template_upcastNamespace;
6+
7+
public class cpp11_shared_ptr_template_upcast_runme
8+
{
9+
static void Main()
10+
{
11+
PrintableDerived pd = cpp11_shared_ptr_template_upcast.MakePrintableDerived(20);
12+
pd.GetResult();
13+
pd.GetFormatted();
14+
}
15+
}

Examples/test-suite/java/Makefile.in

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

Source/Modules/csharp.cxx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,21 +1758,22 @@ class CSHARP:public Language {
17581758
Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
17591759

17601760
if (smart) {
1761-
SwigType *bsmart = Copy(smart);
1761+
String *smartnamestr = SwigType_namestr(smart);
1762+
String *bsmartnamestr = SwigType_namestr(smart);
1763+
17621764
SwigType *rclassname = SwigType_typedef_resolve_all(c_classname);
17631765
SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass);
1764-
Replaceall(bsmart, rclassname, rbaseclass);
1766+
Replaceall(bsmartnamestr, rclassname, rbaseclass);
1767+
17651768
Delete(rclassname);
17661769
Delete(rbaseclass);
1767-
String *smartnamestr = SwigType_namestr(smart);
1768-
String *bsmartnamestr = SwigType_namestr(bsmart);
1770+
17691771
Printv(upcasts_code,
17701772
"SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n",
17711773
" return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n"
17721774
"}\n", "\n", NIL);
17731775
Delete(bsmartnamestr);
17741776
Delete(smartnamestr);
1775-
Delete(bsmart);
17761777
} else {
17771778
Printv(upcasts_code,
17781779
"SWIGEXPORT ", c_baseclass, " * SWIGSTDCALL ", wname, "(", c_classname, " *jarg1) {\n",

Source/Modules/java.cxx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1897,14 +1897,17 @@ class JAVA:public Language {
18971897
String *wname = Swig_name_wrapper(jniname);
18981898
Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method_name);
18991899
if (smart) {
1900-
SwigType *bsmart = Copy(smart);
1900+
String *smartnamestr = SwigType_namestr(smart);
1901+
String *bsmartnamestr = SwigType_namestr(smart);
1902+
19011903
SwigType *rclassname = SwigType_typedef_resolve_all(c_classname);
19021904
SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass);
1903-
Replaceall(bsmart, rclassname, rbaseclass);
1905+
1906+
Replaceall(bsmartnamestr, rclassname, rbaseclass);
1907+
19041908
Delete(rclassname);
19051909
Delete(rbaseclass);
1906-
String *smartnamestr = SwigType_namestr(smart);
1907-
String *bsmartnamestr = SwigType_namestr(bsmart);
1910+
19081911
Printv(upcasts_code,
19091912
"SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
19101913
" jlong baseptr = 0;\n"
@@ -1917,7 +1920,6 @@ class JAVA:public Language {
19171920
"}\n", "\n", NIL);
19181921
Delete(bsmartnamestr);
19191922
Delete(smartnamestr);
1920-
Delete(bsmart);
19211923
} else {
19221924
Printv(upcasts_code,
19231925
"SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
@@ -1928,6 +1930,7 @@ class JAVA:public Language {
19281930
" return baseptr;\n"
19291931
"}\n", "\n", NIL);
19301932
}
1933+
19311934
Delete(wname);
19321935
Delete(jniname);
19331936
}

0 commit comments

Comments
 (0)