From 8bb659680a31da74c096cc5b9b75b2ac4d577199 Mon Sep 17 00:00:00 2001 From: Stepan Neretin Date: Sun, 13 Apr 2025 14:49:15 +0700 Subject: [PATCH] Suppress uninitialized variable warnings for small stack allocations Add macros to disable and re-enable compiler-specific warnings about possibly uninitialized variables (`-Wmaybe-uninitialized` for GCC, `-Wuninitialized` for Clang, and warning C4700 for MSVC). Use these macros in `_PyEvalFramePushAndInit_Ex()` to suppress false positives on stack-allocated arrays like `stack_array`. This also addresses warnings such as the one in `pycore_call.h` when using `small_stack[_PY_FASTCALL_SMALL_STACK]` that may be flagged by GCC's `-Wmaybe-uninitialized`. --- Include/pymacro.h | 17 +++++++++++++++++ Python/ceval.c | 2 ++ 2 files changed, 19 insertions(+) diff --git a/Include/pymacro.h b/Include/pymacro.h index a82f347866e8d0..402195001fe816 100644 --- a/Include/pymacro.h +++ b/Include/pymacro.h @@ -199,4 +199,21 @@ PyAPI_FUNC(uint32_t) Py_PACK_VERSION(int x, int y); #endif // Py_LIMITED_API < 3.14 +#if defined(__clang__) + #define DISABLE_UNINIT_WARNINGS _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wuninitialized\"") + #define ENABLE_UNINIT_WARNINGS _Pragma("clang diagnostic pop") +#elif defined(__GNUC__) || defined(__GNUG__) + #define DISABLE_UNINIT_WARNINGS _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") + #define ENABLE_UNINIT_WARNINGS _Pragma("GCC diagnostic pop") +#elif defined(_MSC_VER) + #define DISABLE_UNINIT_WARNINGS __pragma(warning(push)) \ + __pragma(warning(disable: 4700)) + #define ENABLE_UNINIT_WARNINGS __pragma(warning(pop)) +#else + #define DISABLE_UNINIT_WARNINGS + #define ENABLE_UNINIT_WARNINGS +#endif + #endif /* Py_PYMACRO_H */ diff --git a/Python/ceval.c b/Python/ceval.c index 47d068edac2743..cc6e67e7e42c27 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1814,6 +1814,7 @@ _PyEvalFramePushAndInit_Ex(PyThreadState *tstate, _PyStackRef func, PyObject *kwnames = NULL; _PyStackRef *newargs; PyObject *const *object_array = NULL; + DISABLE_UNINIT_WARNINGS _PyStackRef stack_array[8]; if (has_dict) { object_array = _PyStack_UnpackDict(tstate, _PyTuple_ITEMS(callargs), nargs, kwargs, &kwnames); @@ -1855,6 +1856,7 @@ _PyEvalFramePushAndInit_Ex(PyThreadState *tstate, _PyStackRef func, else if (nargs > 8) { PyMem_Free((void *)newargs); } + ENABLE_UNINIT_WARNINGS /* No need to decref func here because the reference has been stolen by _PyEvalFramePushAndInit. */