Skip to content

Commit 910fd1e

Browse files
committed
[D] Fix occasional undefined behaviour with inheritance hierarchies
Particularly when using virtual inheritance as the pointers weren't correctly upcast from derived class to base class when stored in the base's proxy class. Fixes commented out test code in cpp11_std_unique_ptr_runme and li_std_auto_ptr_runme D tests.
1 parent 5a379d3 commit 910fd1e

File tree

8 files changed

+72
-11
lines changed

8 files changed

+72
-11
lines changed

CHANGES.current

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
77
Version 4.1.0 (in progress)
88
===========================
99

10+
2022-08-05: wsfulton
11+
[D] Fix occasional undefined behaviour with inheritance hierarchies, particularly
12+
when using virtual inheritance as the pointers weren't correctly upcast from derived
13+
class to base class when stored in the base's proxy class.
14+
1015
2022-08-05: wsfulton
1116
[D] Add support for std::unique_ptr in std_unique_ptr.i.
1217
Add support for std::auto_ptr in std_auto_ptr.i.

Examples/test-suite/cpp11_std_unique_ptr.i

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
%inline %{
1111
#include <memory>
1212
#include <string>
13+
//#include <iostream>
1314
#include "swig_examples_lock.h"
1415

1516
class Klass {
@@ -53,8 +54,18 @@ struct KlassInheritance : virtual Klass {
5354
}
5455
};
5556

57+
std::string useKlassRawPtr(Klass* k) {
58+
// std::cout << "useKlassRawPtr " << std::hex << (Klass*)k << std::endl;
59+
std::string s(k->getLabel());
60+
// std::cout << "useKlassRawPtr string: " << s << std::endl;
61+
return s;
62+
}
63+
5664
std::string takeKlassUniquePtr(std::unique_ptr<Klass> k) {
57-
return std::string(k->getLabel());
65+
// std::cout << "takeKlassUniquePtr " << std::hex << (Klass*)k.get() << std::endl;
66+
std::string s(k->getLabel());
67+
// std::cout << "takeKlassUniquePtr string: " << s << std::endl;
68+
return s;
5869
}
5970

6071
bool is_nullptr(Klass *p) {

Examples/test-suite/d/cpp11_std_unique_ptr_runme.1.d

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ void checkCount(int expected_count) {
1313
}
1414

1515
void main() {
16+
// Test raw pointer handling involving virtual inheritance
17+
{
18+
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
19+
checkCount(1);
20+
string s = useKlassRawPtr(kini);
21+
if (s != "KlassInheritanceInput")
22+
throw new Exception("Incorrect string: " ~ s);
23+
}
24+
checkCount(0);
25+
1626
// unique_ptr as input
1727
{
1828
scope Klass kin = new Klass("KlassInput");
@@ -65,7 +75,6 @@ void main() {
6575
}
6676
checkCount(0);
6777

68-
/*
6978
{
7079
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
7180
checkCount(1);
@@ -77,7 +86,6 @@ void main() {
7786
throw new Exception("is_nullptr failed");
7887
} // dispose should not fail, even though already deleted
7988
checkCount(0);
80-
*/
8189

8290
// unique_ptr as output
8391
Klass k1 = makeKlassUniquePtr("first");

Examples/test-suite/d/cpp11_std_unique_ptr_runme.2.d

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ void checkCount(int expected_count) {
1313
}
1414

1515
void main() {
16+
// Test raw pointer handling involving virtual inheritance
17+
{
18+
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
19+
checkCount(1);
20+
string s = useKlassRawPtr(kini);
21+
if (s != "KlassInheritanceInput")
22+
throw new Exception("Incorrect string: " ~ s);
23+
}
24+
checkCount(0);
25+
1626
// unique_ptr as input
1727
{
1828
scope Klass kin = new Klass("KlassInput");
@@ -65,7 +75,6 @@ void main() {
6575
}
6676
checkCount(0);
6777

68-
/*
6978
{
7079
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
7180
checkCount(1);
@@ -77,7 +86,6 @@ void main() {
7786
throw new Exception("is_nullptr failed");
7887
} // dispose should not fail, even though already deleted
7988
checkCount(0);
80-
*/
8189

8290
// unique_ptr as output
8391
Klass k1 = makeKlassUniquePtr("first");

Examples/test-suite/d/li_std_auto_ptr_runme.1.d

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ void checkCount(int expected_count) {
1313
}
1414

1515
void main() {
16+
// Test raw pointer handling involving virtual inheritance
17+
{
18+
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
19+
checkCount(1);
20+
string s = useKlassRawPtr(kini);
21+
if (s != "KlassInheritanceInput")
22+
throw new Exception("Incorrect string: " ~ s);
23+
}
24+
checkCount(0);
25+
1626
// auto_ptr as input
1727
{
1828
scope Klass kin = new Klass("KlassInput");
@@ -65,7 +75,6 @@ void main() {
6575
}
6676
checkCount(0);
6777

68-
/*
6978
{
7079
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
7180
checkCount(1);
@@ -77,7 +86,6 @@ void main() {
7786
throw new Exception("is_nullptr failed");
7887
} // dispose should not fail, even though already deleted
7988
checkCount(0);
80-
*/
8189

8290
// auto_ptr as output
8391
Klass k1 = makeKlassAutoPtr("first");

Examples/test-suite/d/li_std_auto_ptr_runme.2.d

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@ void checkCount(int expected_count) {
1313
}
1414

1515
void main() {
16+
// Test raw pointer handling involving virtual inheritance
17+
{
18+
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
19+
checkCount(1);
20+
string s = useKlassRawPtr(kini);
21+
checkCount(1);
22+
if (s != "KlassInheritanceInput")
23+
throw new Exception("Incorrect string: " ~ s);
24+
}
25+
checkCount(0);
26+
1627
// auto_ptr as input
1728
{
1829
scope Klass kin = new Klass("KlassInput");
@@ -65,7 +76,6 @@ void main() {
6576
}
6677
checkCount(0);
6778

68-
/*
6979
{
7080
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
7181
checkCount(1);
@@ -77,7 +87,6 @@ void main() {
7787
throw new Exception("is_nullptr failed");
7888
} // dispose should not fail, even though already deleted
7989
checkCount(0);
80-
*/
8190

8291
// auto_ptr as output
8392
Klass k1 = makeKlassAutoPtr("first");

Examples/test-suite/li_std_auto_ptr.i

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGPERL) || defined(SWIGTCL) || defined(SWIGOCTAVE) || defined(SWIGJAVASCRIPT) || defined(SWIGD)
1616

1717
%include "std_string.i"
18+
//#include <iostream>
1819
%include "std_auto_ptr.i"
1920

2021
%auto_ptr(Klass)
@@ -100,10 +101,21 @@ struct KlassInheritance : virtual Klass {
100101
}
101102
};
102103

104+
std::string useKlassRawPtr(Klass* k) {
105+
// std::cout << "useKlassRawPtr " << std::hex << (Klass*)k << std::endl;
106+
std::string s(k->getLabel());
107+
// std::cout << "useKlassRawPtr string: " << s << std::endl;
108+
return s;
109+
}
110+
103111
std::string takeKlassAutoPtr(std::auto_ptr<Klass> k) {
104-
return std::string(k->getLabel());
112+
// std::cout << "takeKlassAutoPtr " << std::hex << (Klass*)k.get() << std::endl;
113+
std::string s(k->getLabel());
114+
// std::cout << "takeKlassAutoPtr string: " << s << std::endl;
115+
return s;
105116
}
106117

118+
107119
bool is_nullptr(Klass *p) {
108120
return p == 0;
109121
}

Source/Modules/d.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3402,7 +3402,7 @@ class D : public Language {
34023402
} else {
34033403
Printv(upcasts_code,
34043404
"SWIGEXPORT ", baseclassname, " * ", upcast_wrapper_name,
3405-
"(", baseclassname, " *objectRef) {\n",
3405+
"(", classname, " *objectRef) {\n",
34063406
" return (", baseclassname, " *)objectRef;\n"
34073407
"}\n",
34083408
"\n", NIL);

0 commit comments

Comments
 (0)