From 67c9c5687b2488d36a674c5d60d67617fc8c4b91 Mon Sep 17 00:00:00 2001 From: Matthias Volk Date: Wed, 27 Mar 2024 21:51:03 +0100 Subject: [PATCH] fix: fully qualify usages of concat to protect against ADL (#4955) * Call concat with proper namespace in cast.h * Apply suggestions from code review * tests: add test for ADL on concat Signed-off-by: Henry Schreiner * fix: fully qualify all usages of concat Signed-off-by: Henry Schreiner --------- Signed-off-by: Henry Schreiner Co-authored-by: Henry Schreiner --- include/pybind11/cast.h | 8 +++++--- include/pybind11/eigen/tensor.h | 5 +++-- include/pybind11/functional.h | 3 ++- include/pybind11/numpy.h | 2 +- include/pybind11/stl.h | 3 ++- include/pybind11/typing.h | 11 ++++++----- tests/test_custom_type_casters.cpp | 12 ++++++++++++ 7 files changed, 31 insertions(+), 13 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index ae207758bf..02d9488dae 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -672,8 +672,9 @@ class tuple_caster { return cast(*src, policy, parent); } - static constexpr auto name - = const_name("tuple[") + concat(make_caster::name...) + const_name("]"); + static constexpr auto name = const_name("tuple[") + + ::pybind11::detail::concat(make_caster::name...) + + const_name("]"); template using cast_op_type = type; @@ -1569,7 +1570,8 @@ class argument_loader { static_assert(args_pos == -1 || args_pos == constexpr_first(), "py::args cannot be specified more than once"); - static constexpr auto arg_names = concat(type_descr(make_caster::name)...); + static constexpr auto arg_names + = ::pybind11::detail::concat(type_descr(make_caster::name)...); bool load_args(function_call &call) { return load_impl_sequence(call, indices{}); } diff --git a/include/pybind11/eigen/tensor.h b/include/pybind11/eigen/tensor.h index 25d12baca1..d4ed6c0ca8 100644 --- a/include/pybind11/eigen/tensor.h +++ b/include/pybind11/eigen/tensor.h @@ -70,7 +70,7 @@ struct eigen_tensor_helper struct helper> { - static constexpr auto value = concat(const_name(((void) Is, "?"))...); + static constexpr auto value = ::pybind11::detail::concat(const_name(((void) Is, "?"))...); }; static constexpr auto dimensions_descriptor @@ -104,7 +104,8 @@ struct eigen_tensor_helper< return get_shape() == shape; } - static constexpr auto dimensions_descriptor = concat(const_name()...); + static constexpr auto dimensions_descriptor + = ::pybind11::detail::concat(const_name()...); template static Type *alloc(Args &&...args) { diff --git a/include/pybind11/functional.h b/include/pybind11/functional.h index 87ec4d10cb..6856119cde 100644 --- a/include/pybind11/functional.h +++ b/include/pybind11/functional.h @@ -128,7 +128,8 @@ struct type_caster> { } PYBIND11_TYPE_CASTER(type, - const_name("Callable[[") + concat(make_caster::name...) + const_name("Callable[[") + + ::pybind11::detail::concat(make_caster::name...) + const_name("], ") + make_caster::name + const_name("]")); }; diff --git a/include/pybind11/numpy.h b/include/pybind11/numpy.h index 4eb1e214ea..03abc8e778 100644 --- a/include/pybind11/numpy.h +++ b/include/pybind11/numpy.h @@ -446,7 +446,7 @@ struct array_info> { } static constexpr auto extents = const_name::is_array>( - concat(const_name(), array_info::extents), const_name()); + ::pybind11::detail::concat(const_name(), array_info::extents), const_name()); }; // For numpy we have special handling for arrays of characters, so we don't include // the size in the array extents. diff --git a/include/pybind11/stl.h b/include/pybind11/stl.h index f0334b8f87..71bc5902ef 100644 --- a/include/pybind11/stl.h +++ b/include/pybind11/stl.h @@ -421,7 +421,8 @@ struct variant_caster> { using Type = V; PYBIND11_TYPE_CASTER(Type, - const_name("Union[") + detail::concat(make_caster::name...) + const_name("Union[") + + ::pybind11::detail::concat(make_caster::name...) + const_name("]")); }; diff --git a/include/pybind11/typing.h b/include/pybind11/typing.h index 0ee329d85a..bc275fc50b 100644 --- a/include/pybind11/typing.h +++ b/include/pybind11/typing.h @@ -69,8 +69,9 @@ PYBIND11_NAMESPACE_BEGIN(detail) template struct handle_type_name> { - static constexpr auto name - = const_name("tuple[") + concat(make_caster::name...) + const_name("]"); + static constexpr auto name = const_name("tuple[") + + ::pybind11::detail::concat(make_caster::name...) + + const_name("]"); }; template <> @@ -115,9 +116,9 @@ struct handle_type_name> { template struct handle_type_name> { using retval_type = conditional_t::value, void_type, Return>; - static constexpr auto name = const_name("Callable[[") + concat(make_caster::name...) - + const_name("], ") + make_caster::name - + const_name("]"); + static constexpr auto name + = const_name("Callable[[") + ::pybind11::detail::concat(make_caster::name...) + + const_name("], ") + make_caster::name + const_name("]"); }; PYBIND11_NAMESPACE_END(detail) diff --git a/tests/test_custom_type_casters.cpp b/tests/test_custom_type_casters.cpp index b4af02a452..3cbb8687fb 100644 --- a/tests/test_custom_type_casters.cpp +++ b/tests/test_custom_type_casters.cpp @@ -134,6 +134,16 @@ struct type_caster : public other_lib::my_caster {}; } // namespace detail } // namespace PYBIND11_NAMESPACE +// This simply is required to compile +namespace ADL_issue { +template +OutStringType concat(Args &&...) { + return OutStringType(); +} + +struct test {}; +} // namespace ADL_issue + TEST_SUBMODULE(custom_type_casters, m) { // test_custom_type_casters @@ -206,4 +216,6 @@ TEST_SUBMODULE(custom_type_casters, m) { py::return_value_policy::reference); m.def("other_lib_type", [](other_lib::MyType x) { return x; }); + + m.def("_adl_issue", [](const ADL_issue::test &) {}); }