Skip to content

Commit 06003e8

Browse files
Introduce a new style of warning suppression based on push/pop (#4285)
* Introduce a new warning suppression system * Switch to better name * Nits
1 parent 9907bed commit 06003e8

17 files changed

+173
-163
lines changed

include/pybind11/cast.h

+7-4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
#include <vector>
3030

3131
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
32+
33+
PYBIND11_WARNING_DISABLE_MSVC(4127)
34+
3235
PYBIND11_NAMESPACE_BEGIN(detail)
3336

3437
template <typename type, typename SFINAE = void>
@@ -389,7 +392,7 @@ struct string_caster {
389392

390393
// For UTF-8 we avoid the need for a temporary `bytes` object by using
391394
// `PyUnicode_AsUTF8AndSize`.
392-
if (PYBIND11_SILENCE_MSVC_C4127(UTF_N == 8)) {
395+
if (UTF_N == 8) {
393396
Py_ssize_t size = -1;
394397
const auto *buffer
395398
= reinterpret_cast<const CharT *>(PyUnicode_AsUTF8AndSize(load_src.ptr(), &size));
@@ -416,7 +419,7 @@ struct string_caster {
416419
= reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr()));
417420
size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT);
418421
// Skip BOM for UTF-16/32
419-
if (PYBIND11_SILENCE_MSVC_C4127(UTF_N > 8)) {
422+
if (UTF_N > 8) {
420423
buffer++;
421424
length--;
422425
}
@@ -572,7 +575,7 @@ struct type_caster<CharT, enable_if_t<is_std_char_type<CharT>::value>> {
572575
// figure out how long the first encoded character is in bytes to distinguish between these
573576
// two errors. We also allow want to allow unicode characters U+0080 through U+00FF, as
574577
// those can fit into a single char value.
575-
if (PYBIND11_SILENCE_MSVC_C4127(StringCaster::UTF_N == 8) && str_len > 1 && str_len <= 4) {
578+
if (StringCaster::UTF_N == 8 && str_len > 1 && str_len <= 4) {
576579
auto v0 = static_cast<unsigned char>(value[0]);
577580
// low bits only: 0-127
578581
// 0b110xxxxx - start of 2-byte sequence
@@ -598,7 +601,7 @@ struct type_caster<CharT, enable_if_t<is_std_char_type<CharT>::value>> {
598601
// UTF-16 is much easier: we can only have a surrogate pair for values above U+FFFF, thus a
599602
// surrogate pair with total length 2 instantly indicates a range error (but not a "your
600603
// string was too long" error).
601-
else if (PYBIND11_SILENCE_MSVC_C4127(StringCaster::UTF_N == 16) && str_len == 2) {
604+
else if (StringCaster::UTF_N == 16 && str_len == 2) {
602605
one_char = static_cast<CharT>(value[0]);
603606
if (one_char >= 0xD800 && one_char < 0xE000) {
604607
throw value_error("Character code point not in range(0x10000)");

include/pybind11/detail/common.h

+66-16
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,69 @@
1717
// Additional convention: 0xD = dev
1818
#define PYBIND11_VERSION_HEX 0x020B00D1
1919

20-
#define PYBIND11_NAMESPACE_BEGIN(name) namespace name {
21-
#define PYBIND11_NAMESPACE_END(name) }
20+
// Define some generic pybind11 helper macros for warning management.
21+
//
22+
// Note that compiler-specific push/pop pairs are baked into the
23+
// PYBIND11_NAMESPACE_BEGIN/PYBIND11_NAMESPACE_END pair of macros. Therefore manual
24+
// PYBIND11_WARNING_PUSH/PYBIND11_WARNING_POP are usually only needed in `#include` sections.
25+
//
26+
// If you find you need to suppress a warning, please try to make the suppression as local as
27+
// possible using these macros. Please also be sure to push/pop with the pybind11 macros. Please
28+
// only use compiler specifics if you need to check specific versions, e.g. Apple Clang vs. vanilla
29+
// Clang.
30+
#if defined(_MSC_VER)
31+
# define PYBIND11_COMPILER_MSVC
32+
# define PYBIND11_PRAGMA(...) __pragma(__VA_ARGS__)
33+
# define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(warning(push))
34+
# define PYBIND11_WARNING_POP PYBIND11_PRAGMA(warning(pop))
35+
#elif defined(__INTEL_COMPILER)
36+
# define PYBIND11_COMPILER_INTEL
37+
# define PYBIND11_PRAGMA(...) _Pragma(# __VA_ARGS__)
38+
# define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(warning push)
39+
# define PYBIND11_WARNING_POP PYBIND11_PRAGMA(warning pop)
40+
#elif defined(__clang__)
41+
# define PYBIND11_COMPILER_CLANG
42+
# define PYBIND11_PRAGMA(...) _Pragma(# __VA_ARGS__)
43+
# define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(clang diagnostic push)
44+
# define PYBIND11_WARNING_POP PYBIND11_PRAGMA(clang diagnostic push)
45+
#elif defined(__GNUC__)
46+
# define PYBIND11_COMPILER_GCC
47+
# define PYBIND11_PRAGMA(...) _Pragma(# __VA_ARGS__)
48+
# define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(GCC diagnostic push)
49+
# define PYBIND11_WARNING_POP PYBIND11_PRAGMA(GCC diagnostic pop)
50+
#endif
51+
52+
#ifdef PYBIND11_COMPILER_MSVC
53+
# define PYBIND11_WARNING_DISABLE_MSVC(name) PYBIND11_PRAGMA(warning(disable : name))
54+
#else
55+
# define PYBIND11_WARNING_DISABLE_MSVC(name)
56+
#endif
57+
58+
#ifdef PYBIND11_COMPILER_CLANG
59+
# define PYBIND11_WARNING_DISABLE_CLANG(name) PYBIND11_PRAGMA(clang diagnostic ignored name)
60+
#else
61+
# define PYBIND11_WARNING_DISABLE_CLANG(name)
62+
#endif
63+
64+
#ifdef PYBIND11_COMPILER_GCC
65+
# define PYBIND11_WARNING_DISABLE_GCC(name) PYBIND11_PRAGMA(GCC diagnostic ignored name)
66+
#else
67+
# define PYBIND11_WARNING_DISABLE_GCC(name)
68+
#endif
69+
70+
#ifdef PYBIND11_COMPILER_INTEL
71+
# define PYBIND11_WARNING_DISABLE_INTEL(name) PYBIND11_PRAGMA(warning disable name)
72+
#else
73+
# define PYBIND11_WARNING_DISABLE_INTEL(name)
74+
#endif
75+
76+
#define PYBIND11_NAMESPACE_BEGIN(name) \
77+
namespace name { \
78+
PYBIND11_WARNING_PUSH
79+
80+
#define PYBIND11_NAMESPACE_END(name) \
81+
PYBIND11_WARNING_POP \
82+
}
2283

2384
// Robust support for some features and loading modules compiled against different pybind versions
2485
// requires forcing hidden visibility on pybind code, so we enforce this by setting the attribute
@@ -151,9 +212,9 @@
151212

152213
/// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode
153214
#if defined(_MSC_VER)
154-
# pragma warning(push)
215+
PYBIND11_WARNING_PUSH
216+
PYBIND11_WARNING_DISABLE_MSVC(4505)
155217
// C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed (PyPy only)
156-
# pragma warning(disable : 4505)
157218
# if defined(_DEBUG) && !defined(Py_DEBUG)
158219
// Workaround for a VS 2022 issue.
159220
// NOTE: This workaround knowingly violates the Python.h include order requirement:
@@ -236,7 +297,7 @@
236297
# define _DEBUG
237298
# undef PYBIND11_DEBUG_MARKER
238299
# endif
239-
# pragma warning(pop)
300+
PYBIND11_WARNING_POP
240301
#endif
241302

242303
#include <cstddef>
@@ -1136,17 +1197,6 @@ constexpr
11361197
# define PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(...)
11371198
#endif
11381199

1139-
#if defined(_MSC_VER) // All versions (as of July 2021).
1140-
1141-
// warning C4127: Conditional expression is constant
1142-
constexpr inline bool silence_msvc_c4127(bool cond) { return cond; }
1143-
1144-
# define PYBIND11_SILENCE_MSVC_C4127(...) ::pybind11::detail::silence_msvc_c4127(__VA_ARGS__)
1145-
1146-
#else
1147-
# define PYBIND11_SILENCE_MSVC_C4127(...) __VA_ARGS__
1148-
#endif
1149-
11501200
#if defined(__clang__) \
11511201
&& (defined(__apple_build_version__) /* AppleClang 13.0.0.13000029 was the only data point \
11521202
available. */ \

include/pybind11/detail/init.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
#include "class.h"
1313

1414
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
15+
16+
PYBIND11_WARNING_DISABLE_MSVC(4127)
17+
1518
PYBIND11_NAMESPACE_BEGIN(detail)
1619

1720
template <>
@@ -115,7 +118,7 @@ template <typename Class>
115118
void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {
116119
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
117120
no_nullptr(ptr);
118-
if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias && !is_alias<Class>(ptr)) {
121+
if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
119122
// We're going to try to construct an alias by moving the cpp type. Whether or not
120123
// that succeeds, we still need to destroy the original cpp pointer (either the
121124
// moved away leftover, if the alias construction works, or the value itself if we
@@ -156,7 +159,7 @@ void construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {
156159
auto *ptr = holder_helper<Holder<Class>>::get(holder);
157160
no_nullptr(ptr);
158161
// If we need an alias, check that the held pointer is actually an alias instance
159-
if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias && !is_alias<Class>(ptr)) {
162+
if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
160163
throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance "
161164
"is not an alias instance");
162165
}
@@ -174,7 +177,7 @@ void construct(value_and_holder &v_h, Cpp<Class> &&result, bool need_alias) {
174177
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
175178
static_assert(std::is_move_constructible<Cpp<Class>>::value,
176179
"pybind11::init() return-by-value factory function requires a movable class");
177-
if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias) {
180+
if (Class::has_alias && need_alias) {
178181
construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(result));
179182
} else {
180183
v_h.value_ptr() = new Cpp<Class>(std::move(result));

include/pybind11/eigen/matrix.h

+9-22
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,15 @@
1616
https://stackoverflow.com/questions/2579576/i-dir-vs-isystem-dir
1717
https://stackoverflow.com/questions/1741816/isystem-for-ms-visual-studio-c-compiler
1818
*/
19-
// The C4127 suppression was introduced for Eigen 3.4.0. In theory we could
20-
// make it version specific, or even remove it later, but considering that
21-
// 1. C4127 is generally far more distracting than useful for modern template code, and
22-
// 2. we definitely want to ignore any MSVC warnings originating from Eigen code,
23-
// it is probably best to keep this around indefinitely.
24-
#if defined(_MSC_VER)
25-
# pragma warning(push)
26-
# pragma warning(disable : 4127) // C4127: conditional expression is constant
27-
# pragma warning(disable : 5054) // https://github.com/pybind/pybind11/pull/3741
19+
PYBIND11_WARNING_PUSH
20+
PYBIND11_WARNING_DISABLE_MSVC(5054) // https://github.com/pybind/pybind11/pull/3741
2821
// C5054: operator '&': deprecated between enumerations of different types
29-
#elif defined(__MINGW32__)
30-
# pragma GCC diagnostic push
31-
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
32-
#endif
22+
PYBIND11_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
3323

3424
#include <Eigen/Core>
3525
#include <Eigen/SparseCore>
3626

37-
#if defined(_MSC_VER)
38-
# pragma warning(pop)
39-
#elif defined(__MINGW32__)
40-
# pragma GCC diagnostic pop
41-
#endif
27+
PYBIND11_WARNING_POP
4228

4329
// Eigen prior to 3.2.7 doesn't have proper move constructors--but worse, some classes get implicit
4430
// move constructors that break things. We could detect this an explicitly copy, but an extra copy
@@ -48,6 +34,8 @@ static_assert(EIGEN_VERSION_AT_LEAST(3, 2, 7),
4834

4935
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
5036

37+
PYBIND11_WARNING_DISABLE_MSVC(4127)
38+
5139
// Provide a convenience alias for easier pass-by-ref usage with fully dynamic strides:
5240
using EigenDStride = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
5341
template <typename MatrixType>
@@ -189,8 +177,7 @@ struct EigenProps {
189177
EigenIndex np_rows = a.shape(0), np_cols = a.shape(1),
190178
np_rstride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar)),
191179
np_cstride = a.strides(1) / static_cast<ssize_t>(sizeof(Scalar));
192-
if ((PYBIND11_SILENCE_MSVC_C4127(fixed_rows) && np_rows != rows)
193-
|| (PYBIND11_SILENCE_MSVC_C4127(fixed_cols) && np_cols != cols)) {
180+
if ((fixed_rows && np_rows != rows) || (fixed_cols && np_cols != cols)) {
194181
return false;
195182
}
196183

@@ -203,7 +190,7 @@ struct EigenProps {
203190
stride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar));
204191

205192
if (vector) { // Eigen type is a compile-time vector
206-
if (PYBIND11_SILENCE_MSVC_C4127(fixed) && size != n) {
193+
if (fixed && size != n) {
207194
return false; // Vector size mismatch
208195
}
209196
return {rows == 1 ? 1 : n, cols == 1 ? 1 : n, stride};
@@ -220,7 +207,7 @@ struct EigenProps {
220207
}
221208
return {1, n, stride};
222209
} // Otherwise it's either fully dynamic, or column dynamic; both become a column vector
223-
if (PYBIND11_SILENCE_MSVC_C4127(fixed_rows) && rows != n) {
210+
if (fixed_rows && rows != n) {
224211
return false;
225212
}
226213
return {n, 1, stride};

include/pybind11/eigen/tensor.h

+13-22
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,23 @@
1313
static_assert(__GNUC__ > 5, "Eigen Tensor support in pybind11 requires GCC > 5.0");
1414
#endif
1515

16-
#if defined(_MSC_VER)
17-
# pragma warning(push)
18-
# pragma warning(disable : 4554) // Tensor.h warning
19-
# pragma warning(disable : 4127) // Tensor.h warning
20-
#elif defined(__MINGW32__)
21-
# pragma GCC diagnostic push
22-
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
23-
#endif
16+
// Disable warnings for Eigen
17+
PYBIND11_WARNING_PUSH
18+
PYBIND11_WARNING_DISABLE_MSVC(4554)
19+
PYBIND11_WARNING_DISABLE_MSVC(4127)
20+
PYBIND11_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
2421

2522
#include <unsupported/Eigen/CXX11/Tensor>
2623

27-
#if defined(_MSC_VER)
28-
# pragma warning(pop)
29-
#elif defined(__MINGW32__)
30-
# pragma GCC diagnostic pop
31-
#endif
24+
PYBIND11_WARNING_POP
3225

3326
static_assert(EIGEN_VERSION_AT_LEAST(3, 3, 0),
3427
"Eigen Tensor support in pybind11 requires Eigen >= 3.3.0");
3528

3629
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
3730

31+
PYBIND11_WARNING_DISABLE_MSVC(4127)
32+
3833
PYBIND11_NAMESPACE_BEGIN(detail)
3934

4035
inline bool is_tensor_aligned(const void *data) {
@@ -138,10 +133,8 @@ struct get_tensor_descriptor {
138133
//
139134
// We need to disable the type-limits warning for the inner loop when size = 0.
140135

141-
#if defined(__GNUC__)
142-
# pragma GCC diagnostic push
143-
# pragma GCC diagnostic ignored "-Wtype-limits"
144-
#endif
136+
PYBIND11_WARNING_PUSH
137+
PYBIND11_WARNING_DISABLE_GCC("-Wtype-limits")
145138

146139
template <typename T, int size>
147140
std::vector<T> convert_dsizes_to_vector(const Eigen::DSizes<T, size> &arr) {
@@ -165,9 +158,7 @@ Eigen::DSizes<T, size> get_shape_for_array(const array &arr) {
165158
return result;
166159
}
167160

168-
#if defined(__GNUC__)
169-
# pragma GCC diagnostic pop
170-
#endif
161+
PYBIND11_WARNING_POP
171162

172163
template <typename Type>
173164
struct type_caster<Type, typename eigen_tensor_helper<Type>::ValidType> {
@@ -389,7 +380,7 @@ struct type_caster<Eigen::TensorMap<Type, Options>,
389380

390381
constexpr bool is_aligned = (Options & Eigen::Aligned) != 0;
391382

392-
if (PYBIND11_SILENCE_MSVC_C4127(is_aligned) && !is_tensor_aligned(arr.data())) {
383+
if (is_aligned && !is_tensor_aligned(arr.data())) {
393384
return false;
394385
}
395386

@@ -399,7 +390,7 @@ struct type_caster<Eigen::TensorMap<Type, Options>,
399390
return false;
400391
}
401392

402-
if (PYBIND11_SILENCE_MSVC_C4127(needs_writeable) && !arr.writeable()) {
393+
if (needs_writeable && !arr.writeable()) {
403394
return false;
404395
}
405396

include/pybind11/numpy.h

+8-7
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ static_assert(std::is_signed<Py_intptr_t>::value, "Py_intptr_t must be signed");
3636

3737
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
3838

39+
PYBIND11_WARNING_DISABLE_MSVC(4127)
40+
3941
class array; // Forward declaration
4042

4143
PYBIND11_NAMESPACE_BEGIN(detail)
@@ -875,7 +877,7 @@ class array : public buffer {
875877
*/
876878
template <typename T, ssize_t Dims = -1>
877879
detail::unchecked_mutable_reference<T, Dims> mutable_unchecked() & {
878-
if (PYBIND11_SILENCE_MSVC_C4127(Dims >= 0) && ndim() != Dims) {
880+
if (Dims >= 0 && ndim() != Dims) {
879881
throw std::domain_error("array has incorrect number of dimensions: "
880882
+ std::to_string(ndim()) + "; expected "
881883
+ std::to_string(Dims));
@@ -893,7 +895,7 @@ class array : public buffer {
893895
*/
894896
template <typename T, ssize_t Dims = -1>
895897
detail::unchecked_reference<T, Dims> unchecked() const & {
896-
if (PYBIND11_SILENCE_MSVC_C4127(Dims >= 0) && ndim() != Dims) {
898+
if (Dims >= 0 && ndim() != Dims) {
897899
throw std::domain_error("array has incorrect number of dimensions: "
898900
+ std::to_string(ndim()) + "; expected "
899901
+ std::to_string(Dims));
@@ -1865,9 +1867,10 @@ struct vectorize_helper {
18651867
}
18661868

18671869
auto result = returned_array::create(trivial, shape);
1870+
1871+
PYBIND11_WARNING_PUSH
18681872
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
1869-
# pragma clang diagnostic push
1870-
# pragma clang diagnostic ignored "-Wreturn-std-move"
1873+
PYBIND11_WARNING_DISABLE_CLANG("-Wreturn-std-move")
18711874
#endif
18721875

18731876
if (size == 0) {
@@ -1883,9 +1886,7 @@ struct vectorize_helper {
18831886
}
18841887

18851888
return result;
1886-
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
1887-
# pragma clang diagnostic pop
1888-
#endif
1889+
PYBIND11_WARNING_POP
18891890
}
18901891

18911892
template <size_t... Index, size_t... VIndex, size_t... BIndex>

0 commit comments

Comments
 (0)