Add test for stl.h / stl_bind.h mix.

Manually verified that the ODR guard detects the ODR violation:

```
C++ Info: Debian Clang 13.0.1 C++17 __pybind11_internals_v4_clang_libstdcpp_cxxabi1002_sh_def__
=========================================================== test session starts ============================================================
platform linux -- Python 3.9.12, pytest-6.2.3, py-1.10.0, pluggy-0.13.1 -- /usr/bin/python3
...
================================================================= FAILURES =================================================================
_____________________________________________ test_type_caster_odr_violation_detected_counter ______________________________________________

    def test_type_caster_odr_violation_detected_counter():
        ...
        else:
>           assert num_violations == 1
E           assert 2 == 1
E             +2
E             -1

num_violations = 2

test_type_caster_odr_guard_1.py:51: AssertionError
========================================================= short test summary info ==========================================================
FAILED test_type_caster_odr_guard_1.py::test_type_caster_odr_violation_detected_counter - assert 2 == 1
======================================================= 1 failed, 5 passed in 0.08s ========================================================
```
This commit is contained in:
Ralf W. Grosse-Kunstleve 2022-06-26 06:04:44 -07:00
parent 4e13032e81
commit 3fc4833433
2 changed files with 30 additions and 0 deletions

View File

@ -1,6 +1,11 @@
#define PYBIND11_DETAIL_TYPE_CASTER_ODR_GUARD_IMPL_THROW_DISABLED true
#include "pybind11_tests.h"
// For test of real-world issue.
#include "pybind11/stl.h"
#include <vector>
namespace mrc_ns { // minimal real caster
struct type_mrc {
@ -34,6 +39,10 @@ struct minimal_real_caster {
}
};
// Intentionally not called from Python: this test is to exercise the ODR guard,
// not stl.h or stl_bind.h.
inline void pass_vector_type_mrc(const std::vector<type_mrc> &) {}
} // namespace mrc_ns
namespace pybind11 {
@ -64,4 +73,7 @@ TEST_SUBMODULE(type_caster_odr_guard_1, m) {
return py::none();
#endif
});
// See comment near the bottom of test_type_caster_odr_guard_2.cpp.
m.def("pass_vector_type_mrc", mrc_ns::pass_vector_type_mrc);
}

View File

@ -1,6 +1,11 @@
#define PYBIND11_DETAIL_TYPE_CASTER_ODR_GUARD_IMPL_THROW_DISABLED true
#include "pybind11_tests.h"
// For test of real-world issue.
#include "pybind11/stl_bind.h"
#include <vector>
namespace mrc_ns { // minimal real caster
struct type_mrc {
@ -36,8 +41,14 @@ struct minimal_real_caster {
}
};
// Intentionally not called from Python: this test is to exercise the ODR guard,
// not stl.h or stl_bind.h.
inline void pass_vector_type_mrc(const std::vector<type_mrc> &) {}
} // namespace mrc_ns
PYBIND11_MAKE_OPAQUE(std::vector<mrc_ns::type_mrc>);
namespace pybind11 {
namespace detail {
template <>
@ -48,4 +59,11 @@ struct type_caster<mrc_ns::type_mrc> : mrc_ns::minimal_real_caster {};
TEST_SUBMODULE(type_caster_odr_guard_2, m) {
m.def("type_mrc_to_python", []() { return mrc_ns::type_mrc(202); });
m.def("type_mrc_from_python", [](const mrc_ns::type_mrc &obj) { return obj.value + 200; });
// Uncomment and run test_type_caster_odr_guard_1.py to verify that the
// test_type_caster_odr_violation_detected_counter subtest fails
// (num_violations 2 instead of 1).
// Unlike the "controlled ODR violation" for the minimal_real_caster, this ODR violation is
// completely unsafe, therefore it cannot portably be exercised with predictable results.
// m.def("pass_vector_type_mrc", mrc_ns::pass_vector_type_mrc);
}