diff --git a/bindings/pyroot/cppyy/CPyCppyy/src/Converters.cxx b/bindings/pyroot/cppyy/CPyCppyy/src/Converters.cxx index de36a34b4a89a..e38b34085c7cc 100644 --- a/bindings/pyroot/cppyy/CPyCppyy/src/Converters.cxx +++ b/bindings/pyroot/cppyy/CPyCppyy/src/Converters.cxx @@ -2192,10 +2192,9 @@ template PyObject* CPyCppyy::InstancePtrConverter::FromMemory(void* address) { // construct python object from C++ instance read at
- Cppyy::TCppScope_t actual_class = Cppyy::GetActualClass(fClass, *(void**)address); if (ISCONST) - return BindCppObject(*(void**)address, actual_class); // by pointer value - return BindCppObject(address, actual_class, CPPInstance::kIsReference); // modifiable + return BindCppObject(*(void**)address, fClass); // by pointer value + return BindCppObject(address, fClass, CPPInstance::kIsReference); // modifiable } //---------------------------------------------------------------------------- diff --git a/bindings/pyroot/cppyy/CPyCppyy/src/ProxyWrappers.cxx b/bindings/pyroot/cppyy/CPyCppyy/src/ProxyWrappers.cxx index 9629f15dc4d84..35a76b0552763 100644 --- a/bindings/pyroot/cppyy/CPyCppyy/src/ProxyWrappers.cxx +++ b/bindings/pyroot/cppyy/CPyCppyy/src/ProxyWrappers.cxx @@ -927,19 +927,24 @@ PyObject* CPyCppyy::BindCppObject(Cppyy::TCppObject_t address, // successful, no down-casting is attempted? // TODO: optimize for final classes unsigned new_flags = flags; - if (!isRef && (gPinnedTypes.empty() || gPinnedTypes.find(klass) == gPinnedTypes.end())) { - Cppyy::TCppType_t clActual = Cppyy::GetActualClass(klass, address); - - if (clActual) { - if (clActual != klass) { - intptr_t offset = Cppyy::GetBaseOffset( - clActual, klass, address, -1 /* down-cast */, true /* report errors */); - if (offset != -1) { // may fail if clActual not fully defined - address = (void*)((intptr_t)address + offset); - klass = clActual; + if (gPinnedTypes.empty() || gPinnedTypes.find(klass) == gPinnedTypes.end()) { + if (!isRef) { + Cppyy::TCppType_t clActual = Cppyy::GetActualClass(klass, address); + + if (clActual) { + if (clActual != klass) { + intptr_t offset = Cppyy::GetBaseOffset( + clActual, klass, address, -1 /* down-cast */, true /* report errors */); + if (offset != -1) { // may fail if clActual not fully defined + address = (void*)((intptr_t)address + offset); + klass = clActual; + } } + new_flags |= CPPInstance::kIsActual; } - new_flags |= CPPInstance::kIsActual; + } else { + Cppyy::TCppType_t clActual = Cppyy::GetActualClass(klass, *(void**)address); + klass = clActual; } } diff --git a/bindings/pyroot/cppyy/cppyy/test/test_datatypes.py b/bindings/pyroot/cppyy/cppyy/test/test_datatypes.py index 2e5ab066d03ae..7b66b12e09845 100644 --- a/bindings/pyroot/cppyy/cppyy/test/test_datatypes.py +++ b/bindings/pyroot/cppyy/cppyy/test/test_datatypes.py @@ -2410,6 +2410,41 @@ def test51_polymorphic_types_in_maps(self): else: assert type(v) == gbl.PolymorphicMaps.Derived + def test52_virtual_inheritance(self): + import cppyy + from cppyy import gbl + + cppyy.cppdef(""" + class JetTag { + public: + JetTag() {} + virtual ~JetTag() = default; + int jt = 0; + std::string name = "NAME"; + }; + class BaseTag: public JetTag { + public: + int bt = 1; + } bt; + class JetFitTag: public virtual BaseTag { + public: + int jft = 2; + } jft; + class JetFit: public virtual JetFitTag { + public: + int jf = 3; + } jf; + std::vector make() { + std::vector res; + res.push_back(&bt); + res.push_back(&jft); + res.push_back(&jf); + return res; + } + """) + + for i in gbl.make(): + assert i.name == "NAME" if __name__ == "__main__": exit(pytest.main(args=['-sv', '-ra', __file__]))