• Jason Rhinelander's avatar
    Fix downcasting of base class pointers · 14e70650
    Jason Rhinelander authored
    When we are returned a base class pointer (either directly or via
    shared_from_this()) we detect its runtime type (using `typeid`), then
    end up essentially reinterpret_casting the pointer to the derived type.
    This is invalid when the base class pointer was a non-first base, and we
    end up with an invalid pointer.  We could dynamic_cast to the
    most-derived type, but if *that* type isn't pybind11-registered, the
    resulting pointer given to the base `cast` implementation isn't necessarily valid
    to be reinterpret_cast'ed back to the backup type.
    
    This commit removes the "backup" type argument from the many-argument
    `cast(...)` and instead does the derived-or-pointer type decision and
    type lookup in type_caster_base, where the dynamic_cast has to be to
    correctly get the derived pointer, but also has to do the type lookup to
    ensure that we don't pass the wrong (derived) pointer when the backup
    type (i.e. the type caster intrinsic type) pointer is needed.
    
    Since the lookup is needed before calling the base cast(), this also
    changes the input type to a detail::type_info rather than doing a
    (second) lookup in cast().
    14e70650
test_multiple_inheritance.cpp 6.44 KB