From 1acc9d0555ce6734aa4483a032c087188afaef4c Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 22 Jun 2022 07:43:37 -0700 Subject: [PATCH] type_caster_odr_guard_impl() cleanup --- include/pybind11/cast.h | 6 ++-- .../pybind11/detail/type_caster_odr_guard.h | 36 ++++++++++--------- include/pybind11/detail/typeid.h | 12 +++++-- tests/test_odr_guard_1.cpp | 2 +- tests/test_odr_guard_2.cpp | 2 +- 5 files changed, 34 insertions(+), 24 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 0ad19e6ea..55b20c9a5 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -56,9 +56,9 @@ struct type_caster_odr_guard : type_caster { template int type_caster_odr_guard::translation_unit_local = []() { - odr_guard_impl(std::type_index(typeid(IntrinsicType)), - type_caster::source_file_line.text, - PYBIND11_DETAIL_ODR_GUARD_IMPL_THROW_DISABLED); + type_caster_odr_guard_impl(typeid(IntrinsicType), + type_caster::source_file_line.text, + PYBIND11_DETAIL_TYPE_CASTER_ODR_GUARD_IMPL_THROW_DISABLED); return 0; }(); diff --git a/include/pybind11/detail/type_caster_odr_guard.h b/include/pybind11/detail/type_caster_odr_guard.h index ede37337d..355088a40 100644 --- a/include/pybind11/detail/type_caster_odr_guard.h +++ b/include/pybind11/detail/type_caster_odr_guard.h @@ -4,9 +4,11 @@ #pragma once +// The type_caster ODR guard feature requires Translation-Unit-local entities +// (https://en.cppreference.com/w/cpp/language/tu_local), a C++20 feature, but +// all tested C++17 compilers support this feature already. #if !defined(PYBIND11_TYPE_CASTER_ODR_GUARD_ON) && !defined(PYBIND11_TYPE_CASTER_ODR_GUARD_OFF) \ - && (defined(_MSC_VER) || defined(PYBIND11_CPP20) \ - || (defined(PYBIND11_CPP17) /* && defined(__clang__)*/)) + && (defined(_MSC_VER) || defined(PYBIND11_CPP17)) # define PYBIND11_TYPE_CASTER_ODR_GUARD_ON #endif @@ -32,6 +34,7 @@ # include # include # include +# include # include # include @@ -53,23 +56,24 @@ inline const char *source_file_line_basename(const char *sfl) { return sfl + i_base; } -# ifndef PYBIND11_DETAIL_ODR_GUARD_IMPL_THROW_DISABLED -# define PYBIND11_DETAIL_ODR_GUARD_IMPL_THROW_DISABLED false +# ifndef PYBIND11_DETAIL_TYPE_CASTER_ODR_GUARD_IMPL_THROW_DISABLED +# define PYBIND11_DETAIL_TYPE_CASTER_ODR_GUARD_IMPL_THROW_DISABLED false # endif -template -void odr_guard_impl(const std::type_index &it_ti, - const char *source_file_line, - bool throw_disabled) { +inline void type_caster_odr_guard_impl(const std::type_info &intrinsic_type_info, + const char *source_file_line, + bool throw_disabled) { // std::cout cannot be used here: static initialization could be incomplete. -# define PYBIND11_DETAIL_ODR_GUARD_IMPL_PRINTF_OFF -# ifdef PYBIND11_DETAIL_ODR_GUARD_IMPL_PRINTF_ON - std::fprintf( - stdout, "\nODR_GUARD_IMPL %s %s\n", type_id().c_str(), source_file_line); +# define PYBIND11_DETAIL_TYPE_CASTER_ODR_GUARD_IMPL_PRINTF_OFF +# ifdef PYBIND11_DETAIL_TYPE_CASTER_ODR_GUARD_IMPL_PRINTF_ON + std::fprintf(stdout, + "\nTYPE_CASTER_ODR_GUARD_IMPL %s %s\n", + clean_type_id(intrinsic_type_info.name()).c_str(), + source_file_line); std::fflush(stdout); # endif - std::string sflbn_str{source_file_line_basename(source_file_line)}; - auto ins = odr_guard_registry().insert({it_ti, source_file_line}); + auto ins + = odr_guard_registry().insert({std::type_index(intrinsic_type_info), source_file_line}); auto reg_iter = ins.first; auto added = ins.second; if (!added @@ -77,8 +81,8 @@ void odr_guard_impl(const std::type_index &it_ti, source_file_line_basename(source_file_line)) != 0) { std::string msg("ODR VIOLATION DETECTED: pybind11::detail::type_caster<" - + type_id() + ">: SourceLocation1=\"" + reg_iter->second - + "\", SourceLocation2=\"" + source_file_line + "\""); + + clean_type_id(intrinsic_type_info.name()) + ">: SourceLocation1=\"" + + reg_iter->second + "\", SourceLocation2=\"" + source_file_line + "\""); if (throw_disabled) { std::fprintf(stderr, "\nDISABLED std::system_error: %s\n", msg.c_str()); std::fflush(stderr); diff --git a/include/pybind11/detail/typeid.h b/include/pybind11/detail/typeid.h index 8d99fc028..a67b52135 100644 --- a/include/pybind11/detail/typeid.h +++ b/include/pybind11/detail/typeid.h @@ -20,6 +20,7 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(detail) + /// Erase all occurrences of a substring inline void erase_all(std::string &string, const std::string &search) { for (size_t pos = 0;;) { @@ -46,14 +47,19 @@ PYBIND11_NOINLINE void clean_type_id(std::string &name) { #endif detail::erase_all(name, "pybind11::"); } + +inline std::string clean_type_id(const char *typeid_name) { + std::string name(typeid_name); + detail::clean_type_id(name); + return name; +} + PYBIND11_NAMESPACE_END(detail) /// Return a string representation of a C++ type template static std::string type_id() { - std::string name(typeid(T).name()); - detail::clean_type_id(name); - return name; + return detail::clean_type_id(typeid(T).name()); } PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/tests/test_odr_guard_1.cpp b/tests/test_odr_guard_1.cpp index 77c8265ce..89145c466 100644 --- a/tests/test_odr_guard_1.cpp +++ b/tests/test_odr_guard_1.cpp @@ -1,4 +1,4 @@ -#define PYBIND11_DETAIL_ODR_GUARD_IMPL_THROW_DISABLED true +#define PYBIND11_DETAIL_TYPE_CASTER_ODR_GUARD_IMPL_THROW_DISABLED true #include "pybind11_tests.h" namespace mrc_ns { // minimal real caster diff --git a/tests/test_odr_guard_2.cpp b/tests/test_odr_guard_2.cpp index 3c14f4681..99afba59f 100644 --- a/tests/test_odr_guard_2.cpp +++ b/tests/test_odr_guard_2.cpp @@ -1,4 +1,4 @@ -#define PYBIND11_DETAIL_ODR_GUARD_IMPL_THROW_DISABLED true +#define PYBIND11_DETAIL_TYPE_CASTER_ODR_GUARD_IMPL_THROW_DISABLED true #include "pybind11_tests.h" namespace mrc_ns { // minimal real caster