-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add tests for virtual_inheritance Issue #1256 #1257
base: master
Are you sure you want to change the base?
Conversation
d23fb27
to
b4cde17
Compare
We currently automatically detect multiple inheritance (when registered with pybind) to enable non-simple casting, but simple casting is also invalid when there is single-base, virtual inheritance (pybind#1256). (This happens to work under gcc/clang, but makes MSVC segfault when upcasting). This commit adds detection for a specified base class being a virtual base, and if so, turns on the `multiple_inheritance` flag to mark the class and base as non-simple, and adds tests (which segfault under MSVC without this fix). (Earlier versions can work around the issue by explicitly passing a `py::multiple_inheritance{}` option to the `py::class_<...>` constructor). Co-authored-by: Jason Rhinelander <[email protected]>
b4cde17
to
6a82cfa
Compare
Thanks for the test code! I investigated this some more. It was a bit subtle. The diamond case here actually works properly: It's the non-diamond case, i.e. single inheritance from a virtual base class, where we run into trouble. But in the test case as written in the first commit, registering the diamond case actually fixed both cases! The core issue is that we aren't detecting virtual inheritance as something special: we treat it as ordinary inheritance, which means when we upcast we just We do have a path for proper casting, but it's more complicated, and so we try to only invoke it when necessary: which, currently, means either the class is a base or some ancestor of a base in a registered multiple inheritance class; or you manually specify Now as for your test code, the original commit ended up masking the issue because the diamond inheritance registration marked the The second one by itself, however, already works fine: when the I've amended the test code in the PR to duplicate the base I've also merged a fix into the commit to detect the virtual base, so these tests should pass now. (While I was at it, I squashed and rebased against For current stable, a simple workaround is to add a py::class_<Derived, VirtualBase>(m, "Derived", py::multiple_inheritance{}) Since this commit ends up a bit big (i.e. it required adding a new header, to avoid an unconditional gcc warning in the implementation of the virtual base detection), and because the workaround above is pretty easy, and because this is a fairly rare issue (virtual inheritance is not useful without also having multiple inheritance lurking), I'm leaning against pushing this to to 2.2.x branch. Edit: Fixes #1256 |
I don't think you need to go to the trouble of that is_virtual_base_of implementation if you're willing to restrict yourself to accessible bases; you can just use the fact that static_cast from
|
This is a very simple addition to the tests that covers #1256.
When running these tests as part of the pybind11 tests, they work as expected even with (msvc as detailed in the issue) but compiling the same code as part of another project causes the code to crash.
So currently this PR is just to trigger the automated tests I guess?