Introduce a new style of warning suppression based on push/pop (#4285)

* Introduce a new warning suppression system

* Switch to better name

* Nits
This commit is contained in:
Ethan Steinberg 2022-11-28 07:39:38 -08:00 committed by GitHub
parent 9907bedce5
commit 06003e82b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 173 additions and 163 deletions

View File

@ -29,6 +29,9 @@
#include <vector> #include <vector>
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_WARNING_DISABLE_MSVC(4127)
PYBIND11_NAMESPACE_BEGIN(detail) PYBIND11_NAMESPACE_BEGIN(detail)
template <typename type, typename SFINAE = void> template <typename type, typename SFINAE = void>
@ -389,7 +392,7 @@ struct string_caster {
// For UTF-8 we avoid the need for a temporary `bytes` object by using // For UTF-8 we avoid the need for a temporary `bytes` object by using
// `PyUnicode_AsUTF8AndSize`. // `PyUnicode_AsUTF8AndSize`.
if (PYBIND11_SILENCE_MSVC_C4127(UTF_N == 8)) { if (UTF_N == 8) {
Py_ssize_t size = -1; Py_ssize_t size = -1;
const auto *buffer const auto *buffer
= reinterpret_cast<const CharT *>(PyUnicode_AsUTF8AndSize(load_src.ptr(), &size)); = reinterpret_cast<const CharT *>(PyUnicode_AsUTF8AndSize(load_src.ptr(), &size));
@ -416,7 +419,7 @@ struct string_caster {
= reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr())); = reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr()));
size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT); size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT);
// Skip BOM for UTF-16/32 // Skip BOM for UTF-16/32
if (PYBIND11_SILENCE_MSVC_C4127(UTF_N > 8)) { if (UTF_N > 8) {
buffer++; buffer++;
length--; length--;
} }
@ -572,7 +575,7 @@ public:
// figure out how long the first encoded character is in bytes to distinguish between these // 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 // two errors. We also allow want to allow unicode characters U+0080 through U+00FF, as
// those can fit into a single char value. // 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]); auto v0 = static_cast<unsigned char>(value[0]);
// low bits only: 0-127 // low bits only: 0-127
// 0b110xxxxx - start of 2-byte sequence // 0b110xxxxx - start of 2-byte sequence
@ -598,7 +601,7 @@ public:
// UTF-16 is much easier: we can only have a surrogate pair for values above U+FFFF, thus a // 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 // surrogate pair with total length 2 instantly indicates a range error (but not a "your
// string was too long" error). // 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]); one_char = static_cast<CharT>(value[0]);
if (one_char >= 0xD800 && one_char < 0xE000) { if (one_char >= 0xD800 && one_char < 0xE000) {
throw value_error("Character code point not in range(0x10000)"); throw value_error("Character code point not in range(0x10000)");

View File

@ -17,8 +17,69 @@
// Additional convention: 0xD = dev // Additional convention: 0xD = dev
#define PYBIND11_VERSION_HEX 0x020B00D1 #define PYBIND11_VERSION_HEX 0x020B00D1
#define PYBIND11_NAMESPACE_BEGIN(name) namespace name { // Define some generic pybind11 helper macros for warning management.
#define PYBIND11_NAMESPACE_END(name) } //
// Note that compiler-specific push/pop pairs are baked into the
// PYBIND11_NAMESPACE_BEGIN/PYBIND11_NAMESPACE_END pair of macros. Therefore manual
// PYBIND11_WARNING_PUSH/PYBIND11_WARNING_POP are usually only needed in `#include` sections.
//
// If you find you need to suppress a warning, please try to make the suppression as local as
// possible using these macros. Please also be sure to push/pop with the pybind11 macros. Please
// only use compiler specifics if you need to check specific versions, e.g. Apple Clang vs. vanilla
// Clang.
#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_WARNING_DISABLE_MSVC(name) PYBIND11_PRAGMA(warning(disable : name))
#else
# define PYBIND11_WARNING_DISABLE_MSVC(name)
#endif
#ifdef PYBIND11_COMPILER_CLANG
# define PYBIND11_WARNING_DISABLE_CLANG(name) PYBIND11_PRAGMA(clang diagnostic ignored name)
#else
# define PYBIND11_WARNING_DISABLE_CLANG(name)
#endif
#ifdef PYBIND11_COMPILER_GCC
# define PYBIND11_WARNING_DISABLE_GCC(name) PYBIND11_PRAGMA(GCC diagnostic ignored name)
#else
# define PYBIND11_WARNING_DISABLE_GCC(name)
#endif
#ifdef PYBIND11_COMPILER_INTEL
# define PYBIND11_WARNING_DISABLE_INTEL(name) PYBIND11_PRAGMA(warning disable name)
#else
# define PYBIND11_WARNING_DISABLE_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 // 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 // requires forcing hidden visibility on pybind code, so we enforce this by setting the attribute
@ -151,9 +212,9 @@
/// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode /// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning(push) PYBIND11_WARNING_PUSH
PYBIND11_WARNING_DISABLE_MSVC(4505)
// C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed (PyPy only) // C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed (PyPy only)
# pragma warning(disable : 4505)
# if defined(_DEBUG) && !defined(Py_DEBUG) # if defined(_DEBUG) && !defined(Py_DEBUG)
// Workaround for a VS 2022 issue. // Workaround for a VS 2022 issue.
// NOTE: This workaround knowingly violates the Python.h include order requirement: // NOTE: This workaround knowingly violates the Python.h include order requirement:
@ -236,7 +297,7 @@
# define _DEBUG # define _DEBUG
# undef PYBIND11_DEBUG_MARKER # undef PYBIND11_DEBUG_MARKER
# endif # endif
# pragma warning(pop) PYBIND11_WARNING_POP
#endif #endif
#include <cstddef> #include <cstddef>
@ -1136,17 +1197,6 @@ constexpr
# define PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(...) # define PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(...)
#endif #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__) \ #if defined(__clang__) \
&& (defined(__apple_build_version__) /* AppleClang 13.0.0.13000029 was the only data point \ && (defined(__apple_build_version__) /* AppleClang 13.0.0.13000029 was the only data point \
available. */ \ available. */ \

View File

@ -12,6 +12,9 @@
#include "class.h" #include "class.h"
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_WARNING_DISABLE_MSVC(4127)
PYBIND11_NAMESPACE_BEGIN(detail) PYBIND11_NAMESPACE_BEGIN(detail)
template <> template <>
@ -115,7 +118,7 @@ template <typename Class>
void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) { void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias); PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
no_nullptr(ptr); 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 // 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 // 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 // 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) {
auto *ptr = holder_helper<Holder<Class>>::get(holder); auto *ptr = holder_helper<Holder<Class>>::get(holder);
no_nullptr(ptr); no_nullptr(ptr);
// If we need an alias, check that the held pointer is actually an alias instance // 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 " throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance "
"is not an alias instance"); "is not an alias instance");
} }
@ -174,7 +177,7 @@ void construct(value_and_holder &v_h, Cpp<Class> &&result, bool need_alias) {
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias); PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
static_assert(std::is_move_constructible<Cpp<Class>>::value, static_assert(std::is_move_constructible<Cpp<Class>>::value,
"pybind11::init() return-by-value factory function requires a movable class"); "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)); construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(result));
} else { } else {
v_h.value_ptr() = new Cpp<Class>(std::move(result)); v_h.value_ptr() = new Cpp<Class>(std::move(result));

View File

@ -16,29 +16,15 @@
https://stackoverflow.com/questions/2579576/i-dir-vs-isystem-dir https://stackoverflow.com/questions/2579576/i-dir-vs-isystem-dir
https://stackoverflow.com/questions/1741816/isystem-for-ms-visual-studio-c-compiler 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 PYBIND11_WARNING_PUSH
// make it version specific, or even remove it later, but considering that PYBIND11_WARNING_DISABLE_MSVC(5054) // https://github.com/pybind/pybind11/pull/3741
// 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
// C5054: operator '&': deprecated between enumerations of different types // C5054: operator '&': deprecated between enumerations of different types
#elif defined(__MINGW32__) PYBIND11_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
#include <Eigen/Core> #include <Eigen/Core>
#include <Eigen/SparseCore> #include <Eigen/SparseCore>
#if defined(_MSC_VER) PYBIND11_WARNING_POP
# pragma warning(pop)
#elif defined(__MINGW32__)
# pragma GCC diagnostic pop
#endif
// Eigen prior to 3.2.7 doesn't have proper move constructors--but worse, some classes get implicit // 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 // 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),
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_WARNING_DISABLE_MSVC(4127)
// Provide a convenience alias for easier pass-by-ref usage with fully dynamic strides: // Provide a convenience alias for easier pass-by-ref usage with fully dynamic strides:
using EigenDStride = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>; using EigenDStride = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
template <typename MatrixType> template <typename MatrixType>
@ -189,8 +177,7 @@ struct EigenProps {
EigenIndex np_rows = a.shape(0), np_cols = a.shape(1), EigenIndex np_rows = a.shape(0), np_cols = a.shape(1),
np_rstride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar)), np_rstride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar)),
np_cstride = a.strides(1) / 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) if ((fixed_rows && np_rows != rows) || (fixed_cols && np_cols != cols)) {
|| (PYBIND11_SILENCE_MSVC_C4127(fixed_cols) && np_cols != cols)) {
return false; return false;
} }
@ -203,7 +190,7 @@ struct EigenProps {
stride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar)); stride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar));
if (vector) { // Eigen type is a compile-time vector 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 false; // Vector size mismatch
} }
return {rows == 1 ? 1 : n, cols == 1 ? 1 : n, stride}; return {rows == 1 ? 1 : n, cols == 1 ? 1 : n, stride};
@ -220,7 +207,7 @@ struct EigenProps {
} }
return {1, n, stride}; return {1, n, stride};
} // Otherwise it's either fully dynamic, or column dynamic; both become a column vector } // 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 false;
} }
return {n, 1, stride}; return {n, 1, stride};

View File

@ -13,28 +13,23 @@
static_assert(__GNUC__ > 5, "Eigen Tensor support in pybind11 requires GCC > 5.0"); static_assert(__GNUC__ > 5, "Eigen Tensor support in pybind11 requires GCC > 5.0");
#endif #endif
#if defined(_MSC_VER) // Disable warnings for Eigen
# pragma warning(push) PYBIND11_WARNING_PUSH
# pragma warning(disable : 4554) // Tensor.h warning PYBIND11_WARNING_DISABLE_MSVC(4554)
# pragma warning(disable : 4127) // Tensor.h warning PYBIND11_WARNING_DISABLE_MSVC(4127)
#elif defined(__MINGW32__) PYBIND11_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
#include <unsupported/Eigen/CXX11/Tensor> #include <unsupported/Eigen/CXX11/Tensor>
#if defined(_MSC_VER) PYBIND11_WARNING_POP
# pragma warning(pop)
#elif defined(__MINGW32__)
# pragma GCC diagnostic pop
#endif
static_assert(EIGEN_VERSION_AT_LEAST(3, 3, 0), static_assert(EIGEN_VERSION_AT_LEAST(3, 3, 0),
"Eigen Tensor support in pybind11 requires Eigen >= 3.3.0"); "Eigen Tensor support in pybind11 requires Eigen >= 3.3.0");
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_WARNING_DISABLE_MSVC(4127)
PYBIND11_NAMESPACE_BEGIN(detail) PYBIND11_NAMESPACE_BEGIN(detail)
inline bool is_tensor_aligned(const void *data) { inline bool is_tensor_aligned(const void *data) {
@ -138,10 +133,8 @@ struct get_tensor_descriptor {
// //
// We need to disable the type-limits warning for the inner loop when size = 0. // We need to disable the type-limits warning for the inner loop when size = 0.
#if defined(__GNUC__) PYBIND11_WARNING_PUSH
# pragma GCC diagnostic push PYBIND11_WARNING_DISABLE_GCC("-Wtype-limits")
# pragma GCC diagnostic ignored "-Wtype-limits"
#endif
template <typename T, int size> template <typename T, int size>
std::vector<T> convert_dsizes_to_vector(const Eigen::DSizes<T, size> &arr) { 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) {
return result; return result;
} }
#if defined(__GNUC__) PYBIND11_WARNING_POP
# pragma GCC diagnostic pop
#endif
template <typename Type> template <typename Type>
struct type_caster<Type, typename eigen_tensor_helper<Type>::ValidType> { struct type_caster<Type, typename eigen_tensor_helper<Type>::ValidType> {
@ -389,7 +380,7 @@ struct type_caster<Eigen::TensorMap<Type, Options>,
constexpr bool is_aligned = (Options & Eigen::Aligned) != 0; 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; return false;
} }
@ -399,7 +390,7 @@ struct type_caster<Eigen::TensorMap<Type, Options>,
return false; return false;
} }
if (PYBIND11_SILENCE_MSVC_C4127(needs_writeable) && !arr.writeable()) { if (needs_writeable && !arr.writeable()) {
return false; return false;
} }

View File

@ -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_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_WARNING_DISABLE_MSVC(4127)
class array; // Forward declaration class array; // Forward declaration
PYBIND11_NAMESPACE_BEGIN(detail) PYBIND11_NAMESPACE_BEGIN(detail)
@ -875,7 +877,7 @@ public:
*/ */
template <typename T, ssize_t Dims = -1> template <typename T, ssize_t Dims = -1>
detail::unchecked_mutable_reference<T, Dims> mutable_unchecked() & { 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: " throw std::domain_error("array has incorrect number of dimensions: "
+ std::to_string(ndim()) + "; expected " + std::to_string(ndim()) + "; expected "
+ std::to_string(Dims)); + std::to_string(Dims));
@ -893,7 +895,7 @@ public:
*/ */
template <typename T, ssize_t Dims = -1> template <typename T, ssize_t Dims = -1>
detail::unchecked_reference<T, Dims> unchecked() const & { 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: " throw std::domain_error("array has incorrect number of dimensions: "
+ std::to_string(ndim()) + "; expected " + std::to_string(ndim()) + "; expected "
+ std::to_string(Dims)); + std::to_string(Dims));
@ -1865,9 +1867,10 @@ private:
} }
auto result = returned_array::create(trivial, shape); auto result = returned_array::create(trivial, shape);
PYBIND11_WARNING_PUSH
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING #ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
# pragma clang diagnostic push PYBIND11_WARNING_DISABLE_CLANG("-Wreturn-std-move")
# pragma clang diagnostic ignored "-Wreturn-std-move"
#endif #endif
if (size == 0) { if (size == 0) {
@ -1883,9 +1886,7 @@ private:
} }
return result; return result;
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING PYBIND11_WARNING_POP
# pragma clang diagnostic pop
#endif
} }
template <size_t... Index, size_t... VIndex, size_t... BIndex> template <size_t... Index, size_t... VIndex, size_t... BIndex>

View File

@ -35,6 +35,8 @@
# include <cxxabi.h> # include <cxxabi.h>
#endif #endif
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
/* https://stackoverflow.com/questions/46798456/handling-gccs-noexcept-type-warning /* https://stackoverflow.com/questions/46798456/handling-gccs-noexcept-type-warning
This warning is about ABI compatibility, not code health. This warning is about ABI compatibility, not code health.
It is only actually needed in a couple places, but apparently GCC 7 "generates this warning if It is only actually needed in a couple places, but apparently GCC 7 "generates this warning if
@ -43,11 +45,10 @@
No other GCC version generates this warning. No other GCC version generates this warning.
*/ */
#if defined(__GNUC__) && __GNUC__ == 7 #if defined(__GNUC__) && __GNUC__ == 7
# pragma GCC diagnostic push PYBIND11_WARNING_DISABLE_GCC("-Wnoexcept-type")
# pragma GCC diagnostic ignored "-Wnoexcept-type"
#endif #endif
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_WARNING_DISABLE_MSVC(4127)
PYBIND11_NAMESPACE_BEGIN(detail) PYBIND11_NAMESPACE_BEGIN(detail)
@ -177,22 +178,22 @@ protected:
auto *rec = unique_rec.get(); auto *rec = unique_rec.get();
/* Store the capture object directly in the function record if there is enough space */ /* Store the capture object directly in the function record if there is enough space */
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(capture) <= sizeof(rec->data))) { if (sizeof(capture) <= sizeof(rec->data)) {
/* Without these pragmas, GCC warns that there might not be /* Without these pragmas, GCC warns that there might not be
enough space to use the placement new operator. However, the enough space to use the placement new operator. However, the
'if' statement above ensures that this is the case. */ 'if' statement above ensures that this is the case. */
#if defined(__GNUG__) && __GNUC__ >= 6 && !defined(__clang__) && !defined(__INTEL_COMPILER) PYBIND11_WARNING_PUSH
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wplacement-new" #if defined(__GNUG__) && __GNUC__ >= 6
PYBIND11_WARNING_DISABLE_GCC("-Wplacement-new")
#endif #endif
new ((capture *) &rec->data) capture{std::forward<Func>(f)}; new ((capture *) &rec->data) capture{std::forward<Func>(f)};
#if defined(__GNUG__) && __GNUC__ >= 6 && !defined(__clang__) && !defined(__INTEL_COMPILER)
# pragma GCC diagnostic pop #if !PYBIND11_HAS_STD_LAUNDER
#endif PYBIND11_WARNING_DISABLE_GCC("-Wstrict-aliasing")
#if defined(__GNUG__) && !PYBIND11_HAS_STD_LAUNDER && !defined(__INTEL_COMPILER)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif #endif
// UB without std::launder, but without breaking ABI and/or // UB without std::launder, but without breaking ABI and/or
// a significant refactoring it's "impossible" to solve. // a significant refactoring it's "impossible" to solve.
if (!std::is_trivially_destructible<capture>::value) { if (!std::is_trivially_destructible<capture>::value) {
@ -202,9 +203,7 @@ protected:
data->~capture(); data->~capture();
}; };
} }
#if defined(__GNUG__) && !PYBIND11_HAS_STD_LAUNDER && !defined(__INTEL_COMPILER) PYBIND11_WARNING_POP
# pragma GCC diagnostic pop
#endif
} else { } else {
rec->data[0] = new capture{std::forward<Func>(f)}; rec->data[0] = new capture{std::forward<Func>(f)};
rec->free_data = [](function_record *r) { delete ((capture *) r->data[0]); }; rec->free_data = [](function_record *r) { delete ((capture *) r->data[0]); };
@ -1841,8 +1840,7 @@ private:
if (holder_ptr) { if (holder_ptr) {
init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible<holder_type>()); init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible<holder_type>());
v_h.set_holder_constructed(); v_h.set_holder_constructed();
} else if (PYBIND11_SILENCE_MSVC_C4127(detail::always_construct_holder<holder_type>::value) } else if (detail::always_construct_holder<holder_type>::value || inst->owned) {
|| inst->owned) {
new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>()); new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());
v_h.set_holder_constructed(); v_h.set_holder_constructed();
} }
@ -2876,7 +2874,3 @@ inline function get_overload(const T *this_ptr, const char *name) {
PYBIND11_OVERRIDE_PURE(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), fn, __VA_ARGS__); PYBIND11_OVERRIDE_PURE(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), fn, __VA_ARGS__);
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
#if defined(__GNUC__) && __GNUC__ == 7
# pragma GCC diagnostic pop // -Wnoexcept-type
#endif

View File

@ -33,6 +33,8 @@
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_WARNING_DISABLE_MSVC(4127)
/* A few forward declarations */ /* A few forward declarations */
class handle; class handle;
class object; class object;
@ -884,10 +886,8 @@ object object_or_cast(T &&o);
// Match a PyObject*, which we want to convert directly to handle via its converting constructor // Match a PyObject*, which we want to convert directly to handle via its converting constructor
inline handle object_or_cast(PyObject *ptr) { return ptr; } inline handle object_or_cast(PyObject *ptr) { return ptr; }
#if defined(_MSC_VER) && _MSC_VER < 1920 PYBIND11_WARNING_PUSH
# pragma warning(push) PYBIND11_WARNING_DISABLE_MSVC(4522) // warning C4522: multiple assignment operators specified
# pragma warning(disable : 4522) // warning C4522: multiple assignment operators specified
#endif
template <typename Policy> template <typename Policy>
class accessor : public object_api<accessor<Policy>> { class accessor : public object_api<accessor<Policy>> {
using key_type = typename Policy::key_type; using key_type = typename Policy::key_type;
@ -951,9 +951,7 @@ private:
key_type key; key_type key;
mutable object cache; mutable object cache;
}; };
#if defined(_MSC_VER) && _MSC_VER < 1920 PYBIND11_WARNING_POP
# pragma warning(pop)
#endif
PYBIND11_NAMESPACE_BEGIN(accessor_policies) PYBIND11_NAMESPACE_BEGIN(accessor_policies)
struct obj_attr { struct obj_attr {
@ -1693,7 +1691,7 @@ PYBIND11_NAMESPACE_BEGIN(detail)
// unsigned type: (A)-1 != (B)-1 when A and B are unsigned types of different sizes). // unsigned type: (A)-1 != (B)-1 when A and B are unsigned types of different sizes).
template <typename Unsigned> template <typename Unsigned>
Unsigned as_unsigned(PyObject *o) { Unsigned as_unsigned(PyObject *o) {
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(Unsigned) <= sizeof(unsigned long))) { if (sizeof(Unsigned) <= sizeof(unsigned long)) {
unsigned long v = PyLong_AsUnsignedLong(o); unsigned long v = PyLong_AsUnsignedLong(o);
return v == (unsigned long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v; return v == (unsigned long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v;
} }
@ -1710,7 +1708,7 @@ public:
template <typename T, detail::enable_if_t<std::is_integral<T>::value, int> = 0> template <typename T, detail::enable_if_t<std::is_integral<T>::value, int> = 0>
// NOLINTNEXTLINE(google-explicit-constructor) // NOLINTNEXTLINE(google-explicit-constructor)
int_(T value) { int_(T value) {
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(T) <= sizeof(long))) { if (sizeof(T) <= sizeof(long)) {
if (std::is_signed<T>::value) { if (std::is_signed<T>::value) {
m_ptr = PyLong_FromLong((long) value); m_ptr = PyLong_FromLong((long) value);
} else { } else {

View File

@ -73,6 +73,9 @@ PYBIND11_NAMESPACE_END(detail)
PYBIND11_NAMESPACE_END(pybind11) PYBIND11_NAMESPACE_END(pybind11)
TEST_SUBMODULE(builtin_casters, m) { TEST_SUBMODULE(builtin_casters, m) {
PYBIND11_WARNING_PUSH
PYBIND11_WARNING_DISABLE_MSVC(4127)
// test_simple_string // test_simple_string
m.def("string_roundtrip", [](const char *s) { return s; }); m.def("string_roundtrip", [](const char *s) { return s; });
@ -86,7 +89,7 @@ TEST_SUBMODULE(builtin_casters, m) {
std::wstring wstr; std::wstring wstr;
wstr.push_back(0x61); // a wstr.push_back(0x61); // a
wstr.push_back(0x2e18); // ⸘ wstr.push_back(0x2e18); // ⸘
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(wchar_t) == 2)) { if (sizeof(wchar_t) == 2) {
wstr.push_back(mathbfA16_1); wstr.push_back(mathbfA16_1);
wstr.push_back(mathbfA16_2); wstr.push_back(mathbfA16_2);
} // 𝐀, utf16 } // 𝐀, utf16
@ -113,7 +116,7 @@ TEST_SUBMODULE(builtin_casters, m) {
// Under Python 2.7, invalid unicode UTF-32 characters didn't appear to trigger // Under Python 2.7, invalid unicode UTF-32 characters didn't appear to trigger
// UnicodeDecodeError // UnicodeDecodeError
m.def("bad_utf32_string", [=]() { return std::u32string({a32, char32_t(0xd800), z32}); }); m.def("bad_utf32_string", [=]() { return std::u32string({a32, char32_t(0xd800), z32}); });
if (PYBIND11_SILENCE_MSVC_C4127(sizeof(wchar_t) == 2)) { if (sizeof(wchar_t) == 2) {
m.def("bad_wchar_string", [=]() { m.def("bad_wchar_string", [=]() {
return std::wstring({wchar_t(0x61), wchar_t(0xd800)}); return std::wstring({wchar_t(0x61), wchar_t(0xd800)});
}); });
@ -384,4 +387,6 @@ TEST_SUBMODULE(builtin_casters, m) {
m.def("takes_const_ref", [](const ConstRefCasted &x) { return x.tag; }); m.def("takes_const_ref", [](const ConstRefCasted &x) { return x.tag; });
m.def("takes_const_ref_wrap", m.def("takes_const_ref_wrap",
[](std::reference_wrapper<const ConstRefCasted> x) { return x.get().tag; }); [](std::reference_wrapper<const ConstRefCasted> x) { return x.get().tag; });
PYBIND11_WARNING_POP
} }

View File

@ -22,10 +22,8 @@
#include <utility> #include <utility>
#if defined(_MSC_VER) PYBIND11_WARNING_DISABLE_MSVC(4324)
# pragma warning(disable : 4324)
// warning C4324: structure was padded due to alignment specifier // warning C4324: structure was padded due to alignment specifier
#endif
// test_brace_initialization // test_brace_initialization
struct NoBraceInitialization { struct NoBraceInitialization {

View File

@ -52,15 +52,12 @@ int f1(int x) noexcept { return x + 1; }
#endif #endif
int f2(int x) noexcept(true) { return x + 2; } int f2(int x) noexcept(true) { return x + 2; }
int f3(int x) noexcept(false) { return x + 3; } int f3(int x) noexcept(false) { return x + 3; }
#if defined(__GNUG__) && !defined(__INTEL_COMPILER) PYBIND11_WARNING_PUSH
# pragma GCC diagnostic push PYBIND11_WARNING_DISABLE_GCC("-Wdeprecated")
# pragma GCC diagnostic ignored "-Wdeprecated" PYBIND11_WARNING_DISABLE_CLANG("-Wdeprecated")
#endif
// NOLINTNEXTLINE(modernize-use-noexcept) // NOLINTNEXTLINE(modernize-use-noexcept)
int f4(int x) throw() { return x + 4; } // Deprecated equivalent to noexcept(true) int f4(int x) throw() { return x + 4; } // Deprecated equivalent to noexcept(true)
#if defined(__GNUG__) && !defined(__INTEL_COMPILER) PYBIND11_WARNING_POP
# pragma GCC diagnostic pop
#endif
struct C { struct C {
int m1(int x) noexcept { return x - 1; } int m1(int x) noexcept { return x - 1; }
int m2(int x) const noexcept { return x - 2; } int m2(int x) const noexcept { return x - 2; }
@ -68,17 +65,14 @@ struct C {
int m4(int x) const noexcept(true) { return x - 4; } int m4(int x) const noexcept(true) { return x - 4; }
int m5(int x) noexcept(false) { return x - 5; } int m5(int x) noexcept(false) { return x - 5; }
int m6(int x) const noexcept(false) { return x - 6; } int m6(int x) const noexcept(false) { return x - 6; }
#if defined(__GNUG__) && !defined(__INTEL_COMPILER) PYBIND11_WARNING_PUSH
# pragma GCC diagnostic push PYBIND11_WARNING_DISABLE_GCC("-Wdeprecated")
# pragma GCC diagnostic ignored "-Wdeprecated" PYBIND11_WARNING_DISABLE_CLANG("-Wdeprecated")
#endif
// NOLINTNEXTLINE(modernize-use-noexcept) // NOLINTNEXTLINE(modernize-use-noexcept)
int m7(int x) throw() { return x - 7; } int m7(int x) throw() { return x - 7; }
// NOLINTNEXTLINE(modernize-use-noexcept) // NOLINTNEXTLINE(modernize-use-noexcept)
int m8(int x) const throw() { return x - 8; } int m8(int x) const throw() { return x - 8; }
#if defined(__GNUG__) && !defined(__INTEL_COMPILER) PYBIND11_WARNING_POP
# pragma GCC diagnostic pop
#endif
}; };
} // namespace test_exc_sp } // namespace test_exc_sp
@ -126,14 +120,12 @@ TEST_SUBMODULE(constants_and_functions, m) {
.def("m8", &C::m8); .def("m8", &C::m8);
m.def("f1", f1); m.def("f1", f1);
m.def("f2", f2); m.def("f2", f2);
#if defined(__INTEL_COMPILER)
# pragma warning push PYBIND11_WARNING_PUSH
# pragma warning disable 878 // incompatible exception specifications PYBIND11_WARNING_DISABLE_INTEL(878) // incompatible exception specifications
#endif
m.def("f3", f3); m.def("f3", f3);
#if defined(__INTEL_COMPILER) PYBIND11_WARNING_POP
# pragma warning pop
#endif
m.def("f4", f4); m.def("f4", f4);
// test_function_record_leaks // test_function_record_leaks

View File

@ -13,9 +13,7 @@
#include "constructor_stats.h" #include "constructor_stats.h"
#include "pybind11_tests.h" #include "pybind11_tests.h"
#if defined(_MSC_VER) PYBIND11_WARNING_DISABLE_MSVC(4996)
# pragma warning(disable : 4996) // C4996: std::unary_negation is deprecated
#endif
#include <Eigen/Cholesky> #include <Eigen/Cholesky>

View File

@ -9,7 +9,9 @@
#include "pybind11_tests.h" #include "pybind11_tests.h"
namespace PYBIND11_TEST_EIGEN_TENSOR_NAMESPACE { PYBIND11_NAMESPACE_BEGIN(PYBIND11_TEST_EIGEN_TENSOR_NAMESPACE)
PYBIND11_WARNING_DISABLE_MSVC(4127)
template <typename M> template <typename M>
void reset_tensor(M &x) { void reset_tensor(M &x) {
@ -90,7 +92,7 @@ struct CustomExample {
template <int Options> template <int Options>
void init_tensor_module(pybind11::module &m) { void init_tensor_module(pybind11::module &m) {
const char *needed_options = ""; const char *needed_options = "";
if (PYBIND11_SILENCE_MSVC_C4127(Options == Eigen::ColMajor)) { if (Options == Eigen::ColMajor) {
needed_options = "F"; needed_options = "F";
} else { } else {
needed_options = "C"; needed_options = "C";
@ -330,4 +332,4 @@ void test_module(py::module_ &m) {
init_tensor_module<Eigen::RowMajor>(c_style); init_tensor_module<Eigen::RowMajor>(c_style);
} }
} // namespace PYBIND11_TEST_EIGEN_TENSOR_NAMESPACE PYBIND11_NAMESPACE_END(PYBIND11_TEST_EIGEN_TENSOR_NAMESPACE)

View File

@ -3,11 +3,9 @@
#include <pybind11/embed.h> #include <pybind11/embed.h>
#ifdef _MSC_VER
// Silence MSVC C++17 deprecation warning from Catch regarding std::uncaught_exceptions (up to // Silence MSVC C++17 deprecation warning from Catch regarding std::uncaught_exceptions (up to
// catch 2.0.1; this should be fixed in the next catch release after 2.0.1). // catch 2.0.1; this should be fixed in the next catch release after 2.0.1).
# pragma warning(disable : 4996) PYBIND11_WARNING_DISABLE_MSVC(4996)
#endif
// Catch uses _ internally, which breaks gettext style defines // Catch uses _ internally, which breaks gettext style defines
#ifdef _ #ifdef _

View File

@ -1,10 +1,8 @@
#include <pybind11/embed.h> #include <pybind11/embed.h>
#ifdef _MSC_VER
// Silence MSVC C++17 deprecation warning from Catch regarding std::uncaught_exceptions (up to // Silence MSVC C++17 deprecation warning from Catch regarding std::uncaught_exceptions (up to
// catch 2.0.1; this should be fixed in the next catch release after 2.0.1). // catch 2.0.1; this should be fixed in the next catch release after 2.0.1).
# pragma warning(disable : 4996) PYBIND11_WARNING_DISABLE_MSVC(4996)
#endif
#include <catch.hpp> #include <catch.hpp>
#include <cstdlib> #include <cstdlib>

View File

@ -44,14 +44,13 @@ TEST_SUBMODULE(kwargs_and_defaults, m) {
// test_args_and_kwargs // test_args_and_kwargs
m.def("args_function", [](py::args args) -> py::tuple { m.def("args_function", [](py::args args) -> py::tuple {
PYBIND11_WARNING_PUSH
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING #ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING
# pragma clang diagnostic push PYBIND11_WARNING_DISABLE_CLANG("-Wreturn-std-move")
# pragma clang diagnostic ignored "-Wreturn-std-move"
#endif #endif
return args; return args;
#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING PYBIND11_WARNING_POP
# pragma clang diagnostic pop
#endif
}); });
m.def("args_kwargs_function", [](const py::args &args, const py::kwargs &kwargs) { m.def("args_kwargs_function", [](const py::args &args, const py::kwargs &kwargs) {
return py::make_tuple(args, kwargs); return py::make_tuple(args, kwargs);

View File

@ -132,22 +132,18 @@ struct hash<HashMe> {
// Not a good abs function, but easy to test. // Not a good abs function, but easy to test.
std::string abs(const Vector2 &) { return "abs(Vector2)"; } std::string abs(const Vector2 &) { return "abs(Vector2)"; }
// MSVC & Intel warns about unknown pragmas, and warnings are errors.
#if !defined(_MSC_VER) && !defined(__INTEL_COMPILER)
# pragma GCC diagnostic push
// clang 7.0.0 and Apple LLVM 10.0.1 introduce `-Wself-assign-overloaded` to // clang 7.0.0 and Apple LLVM 10.0.1 introduce `-Wself-assign-overloaded` to
// `-Wall`, which is used here for overloading (e.g. `py::self += py::self `). // `-Wall`, which is used here for overloading (e.g. `py::self += py::self `).
// Here, we suppress the warning using `#pragma diagnostic`. // Here, we suppress the warning
// Taken from: https://github.com/RobotLocomotion/drake/commit/aaf84b46 // Taken from: https://github.com/RobotLocomotion/drake/commit/aaf84b46
// TODO(eric): This could be resolved using a function / functor (e.g. `py::self()`). // TODO(eric): This could be resolved using a function / functor (e.g. `py::self()`).
# if defined(__APPLE__) && defined(__clang__) #if defined(__APPLE__) && defined(__clang__)
# if (__clang_major__ >= 10) # if (__clang_major__ >= 10)
# pragma GCC diagnostic ignored "-Wself-assign-overloaded" PYBIND11_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
# endif # endif
# elif defined(__clang__) #elif defined(__clang__)
# if (__clang_major__ >= 7) # if (__clang_major__ >= 7)
# pragma GCC diagnostic ignored "-Wself-assign-overloaded" PYBIND11_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
# endif
# endif # endif
#endif #endif
@ -283,6 +279,3 @@ TEST_SUBMODULE(operators, m) {
m.def("get_unhashable_HashMe_set", []() { return std::unordered_set<HashMe>{{"one"}}; }); m.def("get_unhashable_HashMe_set", []() { return std::unordered_set<HashMe>{{"one"}}; });
} }
#if !defined(_MSC_VER) && !defined(__INTEL_COMPILER)
# pragma GCC diagnostic pop
#endif