Introduce a new style of warning suppression based on push/pop (#4285)
* Introduce a new warning suppression system
* Switch to better name
* Nits
diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h
index 9b74323..b58dc3a 100644
--- a/include/pybind11/detail/common.h
+++ b/include/pybind11/detail/common.h
@@ -17,8 +17,69 @@
// Additional convention: 0xD = dev
#define PYBIND11_VERSION_HEX 0x020B00D1
-#define PYBIND11_NAMESPACE_BEGIN(name) namespace name {
-#define PYBIND11_NAMESPACE_END(name) }
+// Define some generic pybind11 helper macros for warning management.
+//
+// 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
// 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
#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)
-# 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:
@@ -236,7 +297,7 @@
# define _DEBUG
# undef PYBIND11_DEBUG_MARKER
# endif
-# pragma warning(pop)
+PYBIND11_WARNING_POP
#endif
#include <cstddef>
@@ -1136,17 +1197,6 @@
# 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. */ \