[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.
This commit is contained in:
parent
5a379d317b
commit
910fd1e3cf
8 changed files with 73 additions and 12 deletions
|
|
@ -7,6 +7,11 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
|||
Version 4.1.0 (in progress)
|
||||
===========================
|
||||
|
||||
2022-08-05: wsfulton
|
||||
[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.
|
||||
|
||||
2022-08-05: wsfulton
|
||||
[D] Add support for std::unique_ptr in std_unique_ptr.i.
|
||||
Add support for std::auto_ptr in std_auto_ptr.i.
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
%inline %{
|
||||
#include <memory>
|
||||
#include <string>
|
||||
//#include <iostream>
|
||||
#include "swig_examples_lock.h"
|
||||
|
||||
class Klass {
|
||||
|
|
@ -53,8 +54,18 @@ struct KlassInheritance : virtual Klass {
|
|||
}
|
||||
};
|
||||
|
||||
std::string useKlassRawPtr(Klass* k) {
|
||||
// std::cout << "useKlassRawPtr " << std::hex << (Klass*)k << std::endl;
|
||||
std::string s(k->getLabel());
|
||||
// std::cout << "useKlassRawPtr string: " << s << std::endl;
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string takeKlassUniquePtr(std::unique_ptr<Klass> k) {
|
||||
return std::string(k->getLabel());
|
||||
// std::cout << "takeKlassUniquePtr " << std::hex << (Klass*)k.get() << std::endl;
|
||||
std::string s(k->getLabel());
|
||||
// std::cout << "takeKlassUniquePtr string: " << s << std::endl;
|
||||
return s;
|
||||
}
|
||||
|
||||
bool is_nullptr(Klass *p) {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,16 @@ void checkCount(int expected_count) {
|
|||
}
|
||||
|
||||
void main() {
|
||||
// Test raw pointer handling involving virtual inheritance
|
||||
{
|
||||
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
|
||||
checkCount(1);
|
||||
string s = useKlassRawPtr(kini);
|
||||
if (s != "KlassInheritanceInput")
|
||||
throw new Exception("Incorrect string: " ~ s);
|
||||
}
|
||||
checkCount(0);
|
||||
|
||||
// unique_ptr as input
|
||||
{
|
||||
scope Klass kin = new Klass("KlassInput");
|
||||
|
|
@ -65,7 +75,6 @@ void main() {
|
|||
}
|
||||
checkCount(0);
|
||||
|
||||
/*
|
||||
{
|
||||
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
|
||||
checkCount(1);
|
||||
|
|
@ -77,7 +86,6 @@ void main() {
|
|||
throw new Exception("is_nullptr failed");
|
||||
} // dispose should not fail, even though already deleted
|
||||
checkCount(0);
|
||||
*/
|
||||
|
||||
// unique_ptr as output
|
||||
Klass k1 = makeKlassUniquePtr("first");
|
||||
|
|
|
|||
|
|
@ -13,6 +13,16 @@ void checkCount(int expected_count) {
|
|||
}
|
||||
|
||||
void main() {
|
||||
// Test raw pointer handling involving virtual inheritance
|
||||
{
|
||||
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
|
||||
checkCount(1);
|
||||
string s = useKlassRawPtr(kini);
|
||||
if (s != "KlassInheritanceInput")
|
||||
throw new Exception("Incorrect string: " ~ s);
|
||||
}
|
||||
checkCount(0);
|
||||
|
||||
// unique_ptr as input
|
||||
{
|
||||
scope Klass kin = new Klass("KlassInput");
|
||||
|
|
@ -65,7 +75,6 @@ void main() {
|
|||
}
|
||||
checkCount(0);
|
||||
|
||||
/*
|
||||
{
|
||||
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
|
||||
checkCount(1);
|
||||
|
|
@ -77,7 +86,6 @@ void main() {
|
|||
throw new Exception("is_nullptr failed");
|
||||
} // dispose should not fail, even though already deleted
|
||||
checkCount(0);
|
||||
*/
|
||||
|
||||
// unique_ptr as output
|
||||
Klass k1 = makeKlassUniquePtr("first");
|
||||
|
|
|
|||
|
|
@ -13,6 +13,16 @@ void checkCount(int expected_count) {
|
|||
}
|
||||
|
||||
void main() {
|
||||
// Test raw pointer handling involving virtual inheritance
|
||||
{
|
||||
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
|
||||
checkCount(1);
|
||||
string s = useKlassRawPtr(kini);
|
||||
if (s != "KlassInheritanceInput")
|
||||
throw new Exception("Incorrect string: " ~ s);
|
||||
}
|
||||
checkCount(0);
|
||||
|
||||
// auto_ptr as input
|
||||
{
|
||||
scope Klass kin = new Klass("KlassInput");
|
||||
|
|
@ -65,7 +75,6 @@ void main() {
|
|||
}
|
||||
checkCount(0);
|
||||
|
||||
/*
|
||||
{
|
||||
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
|
||||
checkCount(1);
|
||||
|
|
@ -77,7 +86,6 @@ void main() {
|
|||
throw new Exception("is_nullptr failed");
|
||||
} // dispose should not fail, even though already deleted
|
||||
checkCount(0);
|
||||
*/
|
||||
|
||||
// auto_ptr as output
|
||||
Klass k1 = makeKlassAutoPtr("first");
|
||||
|
|
|
|||
|
|
@ -13,6 +13,17 @@ void checkCount(int expected_count) {
|
|||
}
|
||||
|
||||
void main() {
|
||||
// Test raw pointer handling involving virtual inheritance
|
||||
{
|
||||
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
|
||||
checkCount(1);
|
||||
string s = useKlassRawPtr(kini);
|
||||
checkCount(1);
|
||||
if (s != "KlassInheritanceInput")
|
||||
throw new Exception("Incorrect string: " ~ s);
|
||||
}
|
||||
checkCount(0);
|
||||
|
||||
// auto_ptr as input
|
||||
{
|
||||
scope Klass kin = new Klass("KlassInput");
|
||||
|
|
@ -65,7 +76,6 @@ void main() {
|
|||
}
|
||||
checkCount(0);
|
||||
|
||||
/*
|
||||
{
|
||||
scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
|
||||
checkCount(1);
|
||||
|
|
@ -77,7 +87,6 @@ void main() {
|
|||
throw new Exception("is_nullptr failed");
|
||||
} // dispose should not fail, even though already deleted
|
||||
checkCount(0);
|
||||
*/
|
||||
|
||||
// auto_ptr as output
|
||||
Klass k1 = makeKlassAutoPtr("first");
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGPERL) || defined(SWIGTCL) || defined(SWIGOCTAVE) || defined(SWIGJAVASCRIPT) || defined(SWIGD)
|
||||
|
||||
%include "std_string.i"
|
||||
//#include <iostream>
|
||||
%include "std_auto_ptr.i"
|
||||
|
||||
%auto_ptr(Klass)
|
||||
|
|
@ -100,10 +101,21 @@ struct KlassInheritance : virtual Klass {
|
|||
}
|
||||
};
|
||||
|
||||
std::string takeKlassAutoPtr(std::auto_ptr<Klass> k) {
|
||||
return std::string(k->getLabel());
|
||||
std::string useKlassRawPtr(Klass* k) {
|
||||
// std::cout << "useKlassRawPtr " << std::hex << (Klass*)k << std::endl;
|
||||
std::string s(k->getLabel());
|
||||
// std::cout << "useKlassRawPtr string: " << s << std::endl;
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string takeKlassAutoPtr(std::auto_ptr<Klass> k) {
|
||||
// std::cout << "takeKlassAutoPtr " << std::hex << (Klass*)k.get() << std::endl;
|
||||
std::string s(k->getLabel());
|
||||
// std::cout << "takeKlassAutoPtr string: " << s << std::endl;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
bool is_nullptr(Klass *p) {
|
||||
return p == 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3402,7 +3402,7 @@ private:
|
|||
} else {
|
||||
Printv(upcasts_code,
|
||||
"SWIGEXPORT ", baseclassname, " * ", upcast_wrapper_name,
|
||||
"(", baseclassname, " *objectRef) {\n",
|
||||
"(", classname, " *objectRef) {\n",
|
||||
" return (", baseclassname, " *)objectRef;\n"
|
||||
"}\n",
|
||||
"\n", NIL);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue