Skip to content

Commit b98c9c1

Browse files
committed
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 ======================================================== ```
1 parent a9e9e6f commit b98c9c1

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

tests/test_type_caster_odr_guard_1.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#define PYBIND11_DETAIL_TYPE_CASTER_ODR_GUARD_IMPL_THROW_DISABLED true
22
#include "pybind11_tests.h"
33

4+
// For test of real-world issue.
5+
#include "pybind11/stl.h"
6+
7+
#include <vector>
8+
49
namespace mrc_ns { // minimal real caster
510

611
struct type_mrc {
@@ -34,6 +39,10 @@ struct minimal_real_caster {
3439
}
3540
};
3641

42+
// Intentionally not called from Python: this test is to exercise the ODR guard,
43+
// not stl.h or stl_bind.h.
44+
inline void pass_vector_type_mrc(const std::vector<type_mrc> &) {}
45+
3746
} // namespace mrc_ns
3847

3948
namespace pybind11 {
@@ -64,4 +73,7 @@ TEST_SUBMODULE(type_caster_odr_guard_1, m) {
6473
return py::none();
6574
#endif
6675
});
76+
77+
// See comment near the bottom of test_type_caster_odr_guard_2.cpp.
78+
m.def("pass_vector_type_mrc", mrc_ns::pass_vector_type_mrc);
6779
}

tests/test_type_caster_odr_guard_2.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#define PYBIND11_DETAIL_TYPE_CASTER_ODR_GUARD_IMPL_THROW_DISABLED true
22
#include "pybind11_tests.h"
33

4+
// For test of real-world issue.
5+
#include "pybind11/stl_bind.h"
6+
7+
#include <vector>
8+
49
namespace mrc_ns { // minimal real caster
510

611
struct type_mrc {
@@ -36,8 +41,14 @@ struct minimal_real_caster {
3641
}
3742
};
3843

44+
// Intentionally not called from Python: this test is to exercise the ODR guard,
45+
// not stl.h or stl_bind.h.
46+
inline void pass_vector_type_mrc(const std::vector<type_mrc> &) {}
47+
3948
} // namespace mrc_ns
4049

50+
PYBIND11_MAKE_OPAQUE(std::vector<mrc_ns::type_mrc>);
51+
4152
namespace pybind11 {
4253
namespace detail {
4354
template <>
@@ -48,4 +59,11 @@ struct type_caster<mrc_ns::type_mrc> : mrc_ns::minimal_real_caster {};
4859
TEST_SUBMODULE(type_caster_odr_guard_2, m) {
4960
m.def("type_mrc_to_python", []() { return mrc_ns::type_mrc(202); });
5061
m.def("type_mrc_from_python", [](const mrc_ns::type_mrc &obj) { return obj.value + 200; });
62+
63+
// Uncomment and run test_type_caster_odr_guard_1.py to verify that the
64+
// test_type_caster_odr_violation_detected_counter subtest fails
65+
// (num_violations 2 instead of 1).
66+
// Unlike the "controlled ODR violation" for the minimal_real_caster, this ODR violation is
67+
// completely unsafe, therefore it cannot portably be exercised with predictable results.
68+
// m.def("pass_vector_type_mrc", mrc_ns::pass_vector_type_mrc);
5169
}

0 commit comments

Comments
 (0)