From 80ba996e2695786c79e367dadfdc2766c965ba59 Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Mon, 10 Nov 2025 02:58:05 +0000 Subject: [PATCH 1/2] Supress a few warnings about unused parameters. --- src/greenlet/tests/_test_extension_cpp.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/greenlet/tests/_test_extension_cpp.cpp b/src/greenlet/tests/_test_extension_cpp.cpp index 5cbe6a76..f4df2bf6 100644 --- a/src/greenlet/tests/_test_extension_cpp.cpp +++ b/src/greenlet/tests/_test_extension_cpp.cpp @@ -81,7 +81,7 @@ test_exception_switch(PyObject* UNUSED(self), PyObject* args) static PyObject* -py_test_exception_throw_nonstd(PyObject* self, PyObject* args) +py_test_exception_throw_nonstd(PyObject* UNUSED(self), PyObject* args) { if (!PyArg_ParseTuple(args, "")) return NULL; @@ -91,7 +91,7 @@ py_test_exception_throw_nonstd(PyObject* self, PyObject* args) } static PyObject* -py_test_exception_throw_std(PyObject* self, PyObject* args) +py_test_exception_throw_std(PyObject* UNUSED(self), PyObject* args) { if (!PyArg_ParseTuple(args, "")) return NULL; @@ -101,7 +101,7 @@ py_test_exception_throw_std(PyObject* self, PyObject* args) } static PyObject* -py_test_call(PyObject* self, PyObject* arg) +py_test_call(PyObject* UNUSED(self), PyObject* arg) { PyObject* noargs = PyTuple_New(0); PyObject* ret = PyObject_Call(arg, noargs, nullptr); @@ -121,7 +121,7 @@ py_test_call(PyObject* self, PyObject* arg) * segfault the process. */ static PyObject* -test_exception_switch_and_do_in_g2(PyObject* self, PyObject* args) +test_exception_switch_and_do_in_g2(PyObject* UNUSED(self), PyObject* args) { PyObject* g2func = NULL; PyObject* result = NULL; From 0528de4a586356dfc7fda354e3afb61096eaa45d Mon Sep 17 00:00:00 2001 From: Charlie Lin Date: Mon, 10 Nov 2025 15:23:23 +0000 Subject: [PATCH 2/2] Port UNUSED macro to _test_extension.c --- src/greenlet/tests/_test_extension.c | 42 ++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/src/greenlet/tests/_test_extension.c b/src/greenlet/tests/_test_extension.c index 05e81c03..aa96aa40 100644 --- a/src/greenlet/tests/_test_extension.c +++ b/src/greenlet/tests/_test_extension.c @@ -10,8 +10,32 @@ #define TEST_MODULE_NAME "_test_extension" +// CAUTION: MSVC is stupidly picky: +// +// "The compiler ignores, without warning, any __declspec keywords +// placed after * or & and in front of the variable identifier in a +// declaration." +// (https://docs.microsoft.com/en-us/cpp/cpp/declspec?view=msvc-160) +// +// So pointer return types must be handled differently (because of the +// trailing *), or you get inscrutable compiler warnings like "error +// C2059: syntax error: ''" +// +// In C23, there is a standard syntax for attributes, and +// GCC defines an attribute to use with this: [[gnu:noinline]]. +// In the future, this is expected to become standard. + +#if defined(__GNUC__) || defined(__clang__) +/* We used to check for GCC 4+ or 3.4+, but those compilers are + laughably out of date. Just assume they support it. */ +# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) +#elif defined(_MSC_VER) +/* We used to check for && (_MSC_VER >= 1300) but that's also out of date. */ +# define UNUSED(x) UNUSED_ ## x +#endif + static PyObject* -test_switch(PyObject* self, PyObject* greenlet) +test_switch(PyObject* UNUSED(self), PyObject* greenlet) { PyObject* result = NULL; @@ -33,7 +57,7 @@ test_switch(PyObject* self, PyObject* greenlet) } static PyObject* -test_switch_kwargs(PyObject* self, PyObject* args, PyObject* kwargs) +test_switch_kwargs(PyObject* UNUSED(self), PyObject* args, PyObject* kwargs) { PyGreenlet* g = NULL; PyObject* result = NULL; @@ -58,7 +82,7 @@ test_switch_kwargs(PyObject* self, PyObject* args, PyObject* kwargs) } static PyObject* -test_getcurrent(PyObject* self) +test_getcurrent(PyObject* UNUSED(self)) { PyGreenlet* g = PyGreenlet_GetCurrent(); if (g == NULL || !PyGreenlet_Check(g) || !PyGreenlet_ACTIVE(g)) { @@ -72,7 +96,7 @@ test_getcurrent(PyObject* self) } static PyObject* -test_setparent(PyObject* self, PyObject* arg) +test_setparent(PyObject* UNUSED(self), PyObject* arg) { PyGreenlet* current; PyGreenlet* greenlet = NULL; @@ -97,7 +121,7 @@ test_setparent(PyObject* self, PyObject* arg) } static PyObject* -test_new_greenlet(PyObject* self, PyObject* callable) +test_new_greenlet(PyObject* UNUSED(self), PyObject* callable) { PyObject* result = NULL; PyGreenlet* greenlet = PyGreenlet_New(callable, NULL); @@ -117,21 +141,21 @@ test_new_greenlet(PyObject* self, PyObject* callable) } static PyObject* -test_raise_dead_greenlet(PyObject* self) +test_raise_dead_greenlet(PyObject* UNUSED(self)) { PyErr_SetString(PyExc_GreenletExit, "test GreenletExit exception."); return NULL; } static PyObject* -test_raise_greenlet_error(PyObject* self) +test_raise_greenlet_error(PyObject* UNUSED(self)) { PyErr_SetString(PyExc_GreenletError, "test greenlet.error exception"); return NULL; } static PyObject* -test_throw(PyObject* self, PyGreenlet* g) +test_throw(PyObject* UNUSED(self), PyGreenlet* g) { const char msg[] = "take that sucka!"; PyObject* msg_obj = Py_BuildValue("s", msg); @@ -144,7 +168,7 @@ test_throw(PyObject* self, PyGreenlet* g) } static PyObject* -test_throw_exact(PyObject* self, PyObject* args) +test_throw_exact(PyObject* UNUSED(self), PyObject* args) { PyGreenlet* g = NULL; PyObject* typ = NULL;