From 3fc48334331080b189c989049be303ddb9aea526 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sun, 26 Jun 2022 06:04:44 -0700 Subject: [PATCH] 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 ======================================================== ``` --- tests/test_type_caster_odr_guard_1.cpp | 12 ++++++++++++ tests/test_type_caster_odr_guard_2.cpp | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/tests/test_type_caster_odr_guard_1.cpp b/tests/test_type_caster_odr_guard_1.cpp index 3cafa4da4..0851b0ce2 100644 --- a/tests/test_type_caster_odr_guard_1.cpp +++ b/tests/test_type_caster_odr_guard_1.cpp @@ -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 + 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 &) {} + } // 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); } diff --git a/tests/test_type_caster_odr_guard_2.cpp b/tests/test_type_caster_odr_guard_2.cpp index 126466b7d..ae4631a99 100644 --- a/tests/test_type_caster_odr_guard_2.cpp +++ b/tests/test_type_caster_odr_guard_2.cpp @@ -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 + 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 &) {} + } // namespace mrc_ns +PYBIND11_MAKE_OPAQUE(std::vector); + namespace pybind11 { namespace detail { template <> @@ -48,4 +59,11 @@ struct type_caster : 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); }