Skip to content

Commit 800e5e1

Browse files
authored
Remove type_caster_odr_guard feature. (The feature will continue to live in the pybind11k repo.) (#5255)
This rolls back #4022 (including follow-on tweaks in other PRs).
1 parent 8fd495a commit 800e5e1

12 files changed

+30
-745
lines changed

CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ set(PYBIND11_HEADERS
157157
include/pybind11/detail/smart_holder_sfinae_hooks_only.h
158158
include/pybind11/detail/smart_holder_type_casters.h
159159
include/pybind11/detail/type_caster_base.h
160-
include/pybind11/detail/type_caster_odr_guard.h
161160
include/pybind11/detail/typeid.h
162161
include/pybind11/detail/value_and_holder.h
163162
include/pybind11/attr.h

include/pybind11/cast.h

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include "detail/descr.h"
1515
#include "detail/smart_holder_sfinae_hooks_only.h"
1616
#include "detail/type_caster_base.h"
17-
#include "detail/type_caster_odr_guard.h"
1817
#include "detail/typeid.h"
1918
#include "pytypes.h"
2019

@@ -48,20 +47,8 @@ class type_caster_for_class_ : public type_caster_base<T> {};
4847
template <typename type, typename SFINAE = void>
4948
class type_caster : public type_caster_for_class_<type> {};
5049

51-
#if defined(PYBIND11_ENABLE_TYPE_CASTER_ODR_GUARD)
52-
53-
template <typename type>
54-
using make_caster_for_intrinsic = type_caster_odr_guard<type, type_caster<type>>;
55-
56-
#else
57-
5850
template <typename type>
59-
using make_caster_for_intrinsic = type_caster<type>;
60-
61-
#endif
62-
63-
template <typename type>
64-
using make_caster = make_caster_for_intrinsic<intrinsic_t<type>>;
51+
using make_caster = type_caster<intrinsic_t<type>>;
6552

6653
template <typename T>
6754
struct type_uses_smart_holder_type_caster {
@@ -1179,8 +1166,8 @@ struct return_value_policy_override<
11791166
};
11801167

11811168
// Basic python -> C++ casting; throws if casting fails
1182-
template <typename T>
1183-
make_caster_for_intrinsic<T> &load_type(make_caster_for_intrinsic<T> &conv, const handle &handle) {
1169+
template <typename T, typename SFINAE>
1170+
type_caster<T, SFINAE> &load_type(type_caster<T, SFINAE> &conv, const handle &handle) {
11841171
static_assert(!detail::is_pyobject<T>::value,
11851172
"Internal error: type_caster should only be used for C++ types");
11861173
if (!conv.load(handle, true)) {

include/pybind11/detail/descr.h

Lines changed: 27 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// Copyright (c) 2022 The Pybind Development Team.
2-
// All rights reserved. Use of this source code is governed by a
3-
// BSD-style license that can be found in the LICENSE file.
41
/*
52
pybind11/detail/descr.h: Helper type for concatenating type signatures at compile time
63
@@ -23,106 +20,21 @@ PYBIND11_NAMESPACE_BEGIN(detail)
2320
# define PYBIND11_DESCR_CONSTEXPR const
2421
#endif
2522

26-
// struct src_loc below is to support type_caster_odr_guard.h
27-
// (see https://github.com/pybind/pybind11/pull/4022).
28-
// The ODR guard creates ODR violations itself (see WARNING below & in type_caster_odr_guard.h),
29-
// but is currently the only tool available.
30-
// The ODR is useful to know *for sure* what is safe and what is not, but that is only a
31-
// subset of what actually works in practice, in a specific environment. The implementation
32-
// here exploits the gray area (similar to a white hat hacker).
33-
// The dedicated test_type_caster_odr_guard_1, test_type_caster_odr_guard_2 pair of unit tests
34-
// passes reliably on almost all platforms that meet the compiler requirements (C++17, C++20),
35-
// except one (gcc 9.4.0 debug build).
36-
// In the pybind11 unit tests we want to test the ODR guard in as many environments as possible,
37-
// but it is NOT recommended to enable the guard in regular builds, production, or
38-
// debug. The guard is meant to be used similar to a sanitizer, to check for type_caster ODR
39-
// violations in binaries that are otherwise already fully tested and assumed to be healthy.
40-
//
41-
// * MSVC 2017 does not support __builtin_FILE(), __builtin_LINE().
42-
// * MSVC 193732825 C++17 windows-2020 is failing for unknown reasons.
43-
// * Intel 2021.6.0.20220226 (g++ 9.4 mode) __builtin_LINE() is unreliable
44-
// (line numbers vary between translation units).
45-
#if defined(PYBIND11_ENABLE_TYPE_CASTER_ODR_GUARD_IF_AVAILABLE) \
46-
&& !defined(PYBIND11_ENABLE_TYPE_CASTER_ODR_GUARD) && defined(PYBIND11_CPP17) \
47-
&& !defined(__INTEL_COMPILER) \
48-
&& (!defined(_MSC_VER) \
49-
|| (_MSC_VER >= 1920 /* MSVC 2019 or newer */ \
50-
&& (_MSC_FULL_VER < 193732825 || _MSC_FULL_VER > 193732826 \
51-
|| defined(PYBIND11_CPP20))))
52-
# define PYBIND11_ENABLE_TYPE_CASTER_ODR_GUARD
53-
#endif
54-
55-
#if defined(PYBIND11_ENABLE_TYPE_CASTER_ODR_GUARD)
56-
57-
// Not using std::source_location because:
58-
// 1. "It is unspecified whether the copy/move constructors and the copy/move
59-
// assignment operators of source_location are trivial and/or constexpr."
60-
// (https://en.cppreference.com/w/cpp/utility/source_location).
61-
// 2. A matching no-op stub is needed (below) to avoid code duplication.
62-
struct src_loc {
63-
const char *file;
64-
unsigned line;
65-
66-
constexpr src_loc(const char *file, unsigned line) : file(file), line(line) {}
67-
68-
static constexpr src_loc here(const char *file = __builtin_FILE(),
69-
unsigned line = __builtin_LINE()) {
70-
return src_loc(file, line);
71-
}
72-
73-
constexpr src_loc if_known_or(const src_loc &other) const {
74-
if (file != nullptr) {
75-
return *this;
76-
}
77-
return other;
78-
}
79-
};
80-
81-
#else
82-
83-
// No-op stub, to avoid code duplication, expected to be optimized out completely.
84-
struct src_loc {
85-
constexpr src_loc(const char *, unsigned) {}
86-
87-
static constexpr src_loc here(const char * = nullptr, unsigned = 0) {
88-
return src_loc(nullptr, 0);
89-
}
90-
91-
constexpr src_loc if_known_or(const src_loc &) const { return *this; }
92-
};
93-
94-
#endif
95-
96-
#if defined(PYBIND11_ENABLE_TYPE_CASTER_ODR_GUARD)
97-
namespace { // WARNING: This creates an ODR violation in the ODR guard itself,
98-
// but we do not have any alternative at the moment.
99-
// The ODR violation here is a difference in constexpr between multiple TUs.
100-
// All definitions have the same data layout, the only difference is the
101-
// text const char* pointee (the pointees are identical in value),
102-
// src_loc const char* file pointee (the pointees are different in value),
103-
// src_loc unsigned line value.
104-
// See also: Comment above; WARNING in type_caster_odr_guard.h
105-
#endif
106-
10723
/* Concatenate type signatures at compile time */
10824
template <size_t N, typename... Ts>
10925
struct descr {
11026
char text[N + 1]{'\0'};
111-
const src_loc sloc;
11227

113-
explicit constexpr descr(src_loc sloc) : sloc(sloc) {}
28+
constexpr descr() = default;
11429
// NOLINTNEXTLINE(google-explicit-constructor)
115-
constexpr descr(char const (&s)[N + 1], src_loc sloc = src_loc::here())
116-
: descr(s, make_index_sequence<N>(), sloc) {}
30+
constexpr descr(char const (&s)[N + 1]) : descr(s, make_index_sequence<N>()) {}
11731

11832
template <size_t... Is>
119-
constexpr descr(char const (&s)[N + 1], index_sequence<Is...>, src_loc sloc = src_loc::here())
120-
: text{s[Is]..., '\0'}, sloc(sloc) {}
33+
constexpr descr(char const (&s)[N + 1], index_sequence<Is...>) : text{s[Is]..., '\0'} {}
12134

12235
template <typename... Chars>
12336
// NOLINTNEXTLINE(google-explicit-constructor)
124-
constexpr descr(src_loc sloc, char c, Chars... cs)
125-
: text{c, static_cast<char>(cs)..., '\0'}, sloc(sloc) {}
37+
constexpr descr(char c, Chars... cs) : text{c, static_cast<char>(cs)..., '\0'} {}
12638

12739
static constexpr std::array<const std::type_info *, sizeof...(Ts) + 1> types() {
12840
return {{&typeid(Ts)..., nullptr}};
@@ -135,8 +47,7 @@ constexpr descr<N1 + N2, Ts1..., Ts2...> plus_impl(const descr<N1, Ts1...> &a,
13547
index_sequence<Is1...>,
13648
index_sequence<Is2...>) {
13749
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(b);
138-
return descr<N1 + N2, Ts1..., Ts2...>{
139-
a.sloc.if_known_or(b.sloc), a.text[Is1]..., b.text[Is2]...};
50+
return {a.text[Is1]..., b.text[Is2]...};
14051
}
14152

14253
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
@@ -146,33 +57,27 @@ constexpr descr<N1 + N2, Ts1..., Ts2...> operator+(const descr<N1, Ts1...> &a,
14657
}
14758

14859
template <size_t N>
149-
constexpr descr<N - 1> const_name(char const (&text)[N], src_loc sloc = src_loc::here()) {
150-
return descr<N - 1>(text, sloc);
151-
}
152-
constexpr descr<0> const_name(char const (&)[1], src_loc sloc = src_loc::here()) {
153-
return descr<0>(sloc);
60+
constexpr descr<N - 1> const_name(char const (&text)[N]) {
61+
return descr<N - 1>(text);
15462
}
63+
constexpr descr<0> const_name(char const (&)[1]) { return {}; }
15564

15665
template <size_t Rem, size_t... Digits>
15766
struct int_to_str : int_to_str<Rem / 10, Rem % 10, Digits...> {};
15867
template <size_t... Digits>
15968
struct int_to_str<0, Digits...> {
16069
// WARNING: This only works with C++17 or higher.
161-
// src_loc not tracked (not needed in this situation, at least at the moment).
162-
static constexpr auto digits
163-
= descr<sizeof...(Digits)>(src_loc{nullptr, 0}, ('0' + Digits)...);
70+
static constexpr auto digits = descr<sizeof...(Digits)>(('0' + Digits)...);
16471
};
16572

16673
// Ternary description (like std::conditional)
16774
template <bool B, size_t N1, size_t N2>
168-
constexpr enable_if_t<B, descr<N1 - 1>>
169-
const_name(char const (&text1)[N1], char const (&)[N2], src_loc sloc = src_loc::here()) {
170-
return const_name(text1, sloc);
75+
constexpr enable_if_t<B, descr<N1 - 1>> const_name(char const (&text1)[N1], char const (&)[N2]) {
76+
return const_name(text1);
17177
}
17278
template <bool B, size_t N1, size_t N2>
173-
constexpr enable_if_t<!B, descr<N2 - 1>>
174-
const_name(char const (&)[N1], char const (&text2)[N2], src_loc sloc = src_loc::here()) {
175-
return const_name(text2, sloc);
79+
constexpr enable_if_t<!B, descr<N2 - 1>> const_name(char const (&)[N1], char const (&text2)[N2]) {
80+
return const_name(text2);
17681
}
17782

17883
template <bool B, typename T1, typename T2>
@@ -186,13 +91,12 @@ constexpr enable_if_t<!B, T2> const_name(const T1 &, const T2 &d) {
18691

18792
template <size_t Size>
18893
auto constexpr const_name() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
189-
// src_loc not tracked (not needed in this situation, at least at the moment).
19094
return int_to_str<Size / 10, Size % 10>::digits;
19195
}
19296

19397
template <typename Type>
194-
constexpr descr<1, Type> const_name(src_loc sloc = src_loc::here()) {
195-
return {sloc, '%'};
98+
constexpr descr<1, Type> const_name() {
99+
return {'%'};
196100
}
197101

198102
// If "_" is defined as a macro, py::detail::_ cannot be provided.
@@ -202,18 +106,16 @@ constexpr descr<1, Type> const_name(src_loc sloc = src_loc::here()) {
202106
#ifndef _
203107
# define PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY
204108
template <size_t N>
205-
constexpr descr<N - 1> _(char const (&text)[N], src_loc sloc = src_loc::here()) {
206-
return const_name<N>(text, sloc);
109+
constexpr descr<N - 1> _(char const (&text)[N]) {
110+
return const_name<N>(text);
207111
}
208112
template <bool B, size_t N1, size_t N2>
209-
constexpr enable_if_t<B, descr<N1 - 1>>
210-
_(char const (&text1)[N1], char const (&text2)[N2], src_loc sloc = src_loc::here()) {
211-
return const_name<B, N1, N2>(text1, text2, sloc);
113+
constexpr enable_if_t<B, descr<N1 - 1>> _(char const (&text1)[N1], char const (&text2)[N2]) {
114+
return const_name<B, N1, N2>(text1, text2);
212115
}
213116
template <bool B, size_t N1, size_t N2>
214-
constexpr enable_if_t<!B, descr<N2 - 1>>
215-
_(char const (&text1)[N1], char const (&text2)[N2], src_loc sloc = src_loc::here()) {
216-
return const_name<B, N1, N2>(text1, text2, sloc);
117+
constexpr enable_if_t<!B, descr<N2 - 1>> _(char const (&text1)[N1], char const (&text2)[N2]) {
118+
return const_name<B, N1, N2>(text1, text2);
217119
}
218120
template <bool B, typename T1, typename T2>
219121
constexpr enable_if_t<B, T1> _(const T1 &d1, const T2 &d2) {
@@ -226,16 +128,15 @@ constexpr enable_if_t<!B, T2> _(const T1 &d1, const T2 &d2) {
226128

227129
template <size_t Size>
228130
auto constexpr _() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
229-
// src_loc not tracked (not needed in this situation, at least at the moment).
230131
return const_name<Size>();
231132
}
232133
template <typename Type>
233-
constexpr descr<1, Type> _(src_loc sloc = src_loc::here()) {
234-
return const_name<Type>(sloc);
134+
constexpr descr<1, Type> _() {
135+
return const_name<Type>();
235136
}
236137
#endif // #ifndef _
237138

238-
constexpr descr<0> concat(src_loc sloc = src_loc::here()) { return descr<0>{sloc}; }
139+
constexpr descr<0> concat() { return {}; }
239140

240141
template <size_t N, typename... Ts>
241142
constexpr descr<N, Ts...> concat(const descr<N, Ts...> &descr) {
@@ -246,8 +147,7 @@ constexpr descr<N, Ts...> concat(const descr<N, Ts...> &descr) {
246147
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
247148
constexpr descr<N1 + N2 + 2, Ts1..., Ts2...> operator,(const descr<N1, Ts1...> &a,
248149
const descr<N2, Ts2...> &b) {
249-
// Ensure that src_loc of existing descr is used.
250-
return a + const_name(", ", src_loc{nullptr, 0}) + b;
150+
return a + const_name(", ") + b;
251151
}
252152

253153
template <size_t N, typename... Ts, typename... Args>
@@ -259,20 +159,14 @@ template <size_t N, typename... Ts, typename... Args>
259159
constexpr auto concat(const descr<N, Ts...> &d,
260160
const Args &...args) -> decltype(std::declval<descr<N + 2, Ts...>>()
261161
+ concat(args...)) {
262-
// Ensure that src_loc of existing descr is used.
263-
return d + const_name(", ", src_loc{nullptr, 0}) + concat(args...);
162+
return d + const_name(", ") + concat(args...);
264163
}
265164
#endif
266165

267166
template <size_t N, typename... Ts>
268167
constexpr descr<N + 2, Ts...> type_descr(const descr<N, Ts...> &descr) {
269-
// Ensure that src_loc of existing descr is used.
270-
return const_name("{", src_loc{nullptr, 0}) + descr + const_name("}");
168+
return const_name("{") + descr + const_name("}");
271169
}
272170

273-
#if defined(PYBIND11_ENABLE_TYPE_CASTER_ODR_GUARD)
274-
} // namespace
275-
#endif
276-
277171
PYBIND11_NAMESPACE_END(detail)
278172
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

0 commit comments

Comments
 (0)