Skip to content

Commit

Permalink
Introduce a new warning suppression system
Browse files Browse the repository at this point in the history
  • Loading branch information
EthanSteinberg committed Nov 22, 2022
1 parent 296615a commit ac21ed4
Show file tree
Hide file tree
Showing 17 changed files with 164 additions and 163 deletions.
11 changes: 7 additions & 4 deletions include/pybind11/cast.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
#include <vector>

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

PYBIND11_DISABLE_WARNING_MSVC(4127)

PYBIND11_NAMESPACE_BEGIN(detail)

template <typename type, typename SFINAE = void>
Expand Down Expand Up @@ -389,7 +392,7 @@ struct string_caster {

// For UTF-8 we avoid the need for a temporary `bytes` object by using
// `PyUnicode_AsUTF8AndSize`.
if (PYBIND11_SILENCE_MSVC_C4127(UTF_N == 8)) {
if (UTF_N == 8) {
Py_ssize_t size = -1;
const auto *buffer
= reinterpret_cast<const CharT *>(PyUnicode_AsUTF8AndSize(load_src.ptr(), &size));
Expand All @@ -416,7 +419,7 @@ struct string_caster {
= reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr()));
size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT);
// Skip BOM for UTF-16/32
if (PYBIND11_SILENCE_MSVC_C4127(UTF_N > 8)) {
if (UTF_N > 8) {
buffer++;
length--;
}
Expand Down Expand Up @@ -572,7 +575,7 @@ struct type_caster<CharT, enable_if_t<is_std_char_type<CharT>::value>> {
// figure out how long the first encoded character is in bytes to distinguish between these
// two errors. We also allow want to allow unicode characters U+0080 through U+00FF, as
// those can fit into a single char value.
if (PYBIND11_SILENCE_MSVC_C4127(StringCaster::UTF_N == 8) && str_len > 1 && str_len <= 4) {
if (StringCaster::UTF_N == 8 && str_len > 1 && str_len <= 4) {
auto v0 = static_cast<unsigned char>(value[0]);
// low bits only: 0-127
// 0b110xxxxx - start of 2-byte sequence
Expand All @@ -598,7 +601,7 @@ struct type_caster<CharT, enable_if_t<is_std_char_type<CharT>::value>> {
// UTF-16 is much easier: we can only have a surrogate pair for values above U+FFFF, thus a
// surrogate pair with total length 2 instantly indicates a range error (but not a "your
// string was too long" error).
else if (PYBIND11_SILENCE_MSVC_C4127(StringCaster::UTF_N == 16) && str_len == 2) {
else if (StringCaster::UTF_N == 16 && str_len == 2) {
one_char = static_cast<CharT>(value[0]);
if (one_char >= 0xD800 && one_char < 0xE000) {
throw value_error("Character code point not in range(0x10000)");
Expand Down
73 changes: 57 additions & 16 deletions include/pybind11/detail/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,60 @@
// Additional convention: 0xD = dev
#define PYBIND11_VERSION_HEX 0x020B00D1

#define PYBIND11_NAMESPACE_BEGIN(name) namespace name {
#define PYBIND11_NAMESPACE_END(name) }
// You should never need to push and pop manually as these are done in namespace begin and end
#if defined(_MSC_VER)
# define PYBIND11_COMPILER_MSVC
# define PYBIND11_PRAGMA(...) __pragma(__VA_ARGS__)
# define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(warning(push))
# define PYBIND11_WARNING_POP PYBIND11_PRAGMA(warning(pop))
#elif defined(__INTEL_COMPILER)
# define PYBIND11_COMPILER_INTEL
# define PYBIND11_PRAGMA(...) _Pragma(# __VA_ARGS__)
# define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(warning push)
# define PYBIND11_WARNING_POP PYBIND11_PRAGMA(warning pop)
#elif defined(__clang__)
# define PYBIND11_COMPILER_CLANG
# define PYBIND11_PRAGMA(...) _Pragma(# __VA_ARGS__)
# define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(clang diagnostic push)
# define PYBIND11_WARNING_POP PYBIND11_PRAGMA(clang diagnostic push)
#elif defined(__GNUC__)
# define PYBIND11_COMPILER_GCC
# define PYBIND11_PRAGMA(...) _Pragma(# __VA_ARGS__)
# define PYBIND11_WARNING_PUSH PYBIND11_PRAGMA(GCC diagnostic push)
# define PYBIND11_WARNING_POP PYBIND11_PRAGMA(GCC diagnostic pop)
#endif

#ifdef PYBIND11_COMPILER_MSVC
# define PYBIND11_DISABLE_WARNING_MSVC(name) PYBIND11_PRAGMA(warning(disable : name))
#else
# define PYBIND11_DISABLE_WARNING_MSVC(name)
#endif

#ifdef PYBIND11_COMPILER_CLANG
# define PYBIND11_DISABLE_WARNING_CLANG(name) PYBIND11_PRAGMA(clang diagnostic ignored name)
#else
# define PYBIND11_DISABLE_WARNING_CLANG(name)
#endif

#ifdef PYBIND11_COMPILER_GCC
# define PYBIND11_DISABLE_WARNING_GCC(name) PYBIND11_PRAGMA(GCC diagnostic ignored name)
#else
# define PYBIND11_DISABLE_WARNING_GCC(name)
#endif

#ifdef PYBIND11_COMPILER_INTEL
# define PYBIND11_DISABLE_WARNING_INTEL(name) PYBIND11_PRAGMA(warning disable name)
#else
# define PYBIND11_DISABLE_WARNING_INTEL(name)
#endif

#define PYBIND11_NAMESPACE_BEGIN(name) \
namespace name { \
PYBIND11_WARNING_PUSH

#define PYBIND11_NAMESPACE_END(name) \
PYBIND11_WARNING_POP \
}

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

/// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode
#if defined(_MSC_VER)
# pragma warning(push)
PYBIND11_WARNING_PUSH
PYBIND11_DISABLE_WARNING_MSVC(4505)
// C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed (PyPy only)
# pragma warning(disable : 4505)
# if defined(_DEBUG) && !defined(Py_DEBUG)
// Workaround for a VS 2022 issue.
// NOTE: This workaround knowingly violates the Python.h include order requirement:
Expand Down Expand Up @@ -236,7 +288,7 @@
# define _DEBUG
# undef PYBIND11_DEBUG_MARKER
# endif
# pragma warning(pop)
PYBIND11_WARNING_POP
#endif

#include <cstddef>
Expand Down Expand Up @@ -1136,17 +1188,6 @@ constexpr
# define PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(...)
#endif

#if defined(_MSC_VER) // All versions (as of July 2021).

// warning C4127: Conditional expression is constant
constexpr inline bool silence_msvc_c4127(bool cond) { return cond; }

# define PYBIND11_SILENCE_MSVC_C4127(...) ::pybind11::detail::silence_msvc_c4127(__VA_ARGS__)

#else
# define PYBIND11_SILENCE_MSVC_C4127(...) __VA_ARGS__
#endif

#if defined(__clang__) \
&& (defined(__apple_build_version__) /* AppleClang 13.0.0.13000029 was the only data point \
available. */ \
Expand Down
9 changes: 6 additions & 3 deletions include/pybind11/detail/init.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
#include "class.h"

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

PYBIND11_DISABLE_WARNING_MSVC(4127)

PYBIND11_NAMESPACE_BEGIN(detail)

template <>
Expand Down Expand Up @@ -115,7 +118,7 @@ template <typename Class>
void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
no_nullptr(ptr);
if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias && !is_alias<Class>(ptr)) {
if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
// We're going to try to construct an alias by moving the cpp type. Whether or not
// that succeeds, we still need to destroy the original cpp pointer (either the
// moved away leftover, if the alias construction works, or the value itself if we
Expand Down Expand Up @@ -156,7 +159,7 @@ void construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {
auto *ptr = holder_helper<Holder<Class>>::get(holder);
no_nullptr(ptr);
// If we need an alias, check that the held pointer is actually an alias instance
if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias && !is_alias<Class>(ptr)) {
if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance "
"is not an alias instance");
}
Expand All @@ -174,7 +177,7 @@ void construct(value_and_holder &v_h, Cpp<Class> &&result, bool need_alias) {
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
static_assert(std::is_move_constructible<Cpp<Class>>::value,
"pybind11::init() return-by-value factory function requires a movable class");
if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias) {
if (Class::has_alias && need_alias) {
construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(result));
} else {
v_h.value_ptr() = new Cpp<Class>(std::move(result));
Expand Down
31 changes: 9 additions & 22 deletions include/pybind11/eigen/matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,15 @@
https://stackoverflow.com/questions/2579576/i-dir-vs-isystem-dir
https://stackoverflow.com/questions/1741816/isystem-for-ms-visual-studio-c-compiler
*/
// The C4127 suppression was introduced for Eigen 3.4.0. In theory we could
// make it version specific, or even remove it later, but considering that
// 1. C4127 is generally far more distracting than useful for modern template code, and
// 2. we definitely want to ignore any MSVC warnings originating from Eigen code,
// it is probably best to keep this around indefinitely.
#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable : 4127) // C4127: conditional expression is constant
# pragma warning(disable : 5054) // https://github.com/pybind/pybind11/pull/3741
PYBIND11_WARNING_PUSH
PYBIND11_DISABLE_WARNING_MSVC(5054) // https://github.com/pybind/pybind11/pull/3741
// C5054: operator '&': deprecated between enumerations of different types
#elif defined(__MINGW32__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
PYBIND11_DISABLE_WARNING_GCC("-Wmaybe-uninitialized")

#include <Eigen/Core>
#include <Eigen/SparseCore>

#if defined(_MSC_VER)
# pragma warning(pop)
#elif defined(__MINGW32__)
# pragma GCC diagnostic pop
#endif
PYBIND11_WARNING_POP

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

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

PYBIND11_DISABLE_WARNING_MSVC(4127)

// Provide a convenience alias for easier pass-by-ref usage with fully dynamic strides:
using EigenDStride = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
template <typename MatrixType>
Expand Down Expand Up @@ -189,8 +177,7 @@ struct EigenProps {
EigenIndex np_rows = a.shape(0), np_cols = a.shape(1),
np_rstride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar)),
np_cstride = a.strides(1) / static_cast<ssize_t>(sizeof(Scalar));
if ((PYBIND11_SILENCE_MSVC_C4127(fixed_rows) && np_rows != rows)
|| (PYBIND11_SILENCE_MSVC_C4127(fixed_cols) && np_cols != cols)) {
if ((fixed_rows && np_rows != rows) || (fixed_cols && np_cols != cols)) {
return false;
}

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

if (vector) { // Eigen type is a compile-time vector
if (PYBIND11_SILENCE_MSVC_C4127(fixed) && size != n) {
if (fixed && size != n) {
return false; // Vector size mismatch
}
return {rows == 1 ? 1 : n, cols == 1 ? 1 : n, stride};
Expand All @@ -220,7 +207,7 @@ struct EigenProps {
}
return {1, n, stride};
} // Otherwise it's either fully dynamic, or column dynamic; both become a column vector
if (PYBIND11_SILENCE_MSVC_C4127(fixed_rows) && rows != n) {
if (fixed_rows && rows != n) {
return false;
}
return {n, 1, stride};
Expand Down
35 changes: 13 additions & 22 deletions include/pybind11/eigen/tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,23 @@
static_assert(__GNUC__ > 5, "Eigen Tensor support in pybind11 requires GCC > 5.0");
#endif

#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable : 4554) // Tensor.h warning
# pragma warning(disable : 4127) // Tensor.h warning
#elif defined(__MINGW32__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
// Disable warnings for Eigen
PYBIND11_WARNING_PUSH
PYBIND11_DISABLE_WARNING_MSVC(4554)
PYBIND11_DISABLE_WARNING_MSVC(4127)
PYBIND11_DISABLE_WARNING_GCC("-Wmaybe-uninitialized")

#include <unsupported/Eigen/CXX11/Tensor>

#if defined(_MSC_VER)
# pragma warning(pop)
#elif defined(__MINGW32__)
# pragma GCC diagnostic pop
#endif
PYBIND11_WARNING_POP

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

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

PYBIND11_DISABLE_WARNING_MSVC(4127)

PYBIND11_NAMESPACE_BEGIN(detail)

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

#if defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wtype-limits"
#endif
PYBIND11_WARNING_PUSH
PYBIND11_DISABLE_WARNING_GCC("-Wtype-limits")

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

#if defined(__GNUC__)
# pragma GCC diagnostic pop
#endif
PYBIND11_WARNING_POP

template <typename Type>
struct type_caster<Type, typename eigen_tensor_helper<Type>::ValidType> {
Expand Down Expand Up @@ -389,7 +380,7 @@ struct type_caster<Eigen::TensorMap<Type, Options>,

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

if (PYBIND11_SILENCE_MSVC_C4127(is_aligned) && !is_tensor_aligned(arr.data())) {
if (is_aligned && !is_tensor_aligned(arr.data())) {
return false;
}

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

if (PYBIND11_SILENCE_MSVC_C4127(needs_writeable) && !arr.writeable()) {
if (needs_writeable && !arr.writeable()) {
return false;
}

Expand Down
15 changes: 8 additions & 7 deletions include/pybind11/numpy.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ static_assert(std::is_signed<Py_intptr_t>::value, "Py_intptr_t must be signed");

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

PYBIND11_DISABLE_WARNING_MSVC(4127)

class array; // Forward declaration

PYBIND11_NAMESPACE_BEGIN(detail)
Expand Down Expand Up @@ -875,7 +877,7 @@ class array : public buffer {
*/
template <typename T, ssize_t Dims = -1>
detail::unchecked_mutable_reference<T, Dims> mutable_unchecked() & {
if (PYBIND11_SILENCE_MSVC_C4127(Dims >= 0) && ndim() != Dims) {
if (Dims >= 0 && ndim() != Dims) {
throw std::domain_error("array has incorrect number of dimensions: "
+ std::to_string(ndim()) + "; expected "
+ std::to_string(Dims));
Expand All @@ -893,7 +895,7 @@ class array : public buffer {
*/
template <typename T, ssize_t Dims = -1>
detail::unchecked_reference<T, Dims> unchecked() const & {
if (PYBIND11_SILENCE_MSVC_C4127(Dims >= 0) && ndim() != Dims) {
if (Dims >= 0 && ndim() != Dims) {
throw std::domain_error("array has incorrect number of dimensions: "
+ std::to_string(ndim()) + "; expected "
+ std::to_string(Dims));
Expand Down Expand Up @@ -1865,9 +1867,10 @@ struct vectorize_helper {
}

auto result = returned_array::create(trivial, shape);

PYBIND11_WARNING_PUSH
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wreturn-std-move"
PYBIND11_DISABLE_WARNING_CLANG("-Wreturn-std-move")
#endif

if (size == 0) {
Expand All @@ -1883,9 +1886,7 @@ struct vectorize_helper {
}

return result;
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
# pragma clang diagnostic pop
#endif
PYBIND11_WARNING_POP
}

template <size_t... Index, size_t... VIndex, size_t... BIndex>
Expand Down
Loading

0 comments on commit ac21ed4

Please sign in to comment.