From e6f4de57ffd175870e513ffa387fa6e7eaaeaed2 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 24 Mar 2020 07:55:00 +0100 Subject: [PATCH] bpo-40052: Fix alignment issue in PyVectorcall_Function() In file included from /usr/include/python3.8/Python.h:147: In file included from /usr/include/python3.8/abstract.h:837: /usr/include/python3.8/cpython/abstract.h:91:11: error: cast from 'char *' to 'vectorcallfunc *' (aka 'struct _object *(**)(struct _object *, struct _object *const *, unsigned long, struct _object *)') increases required alignment from 1 to 8 [-Werror,-Wcast-align] ptr = (vectorcallfunc*)(((char *)callable) + offset); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 error generated. Signed-off-by: Andreas Schneider --- Include/cpython/abstract.h | 9 ++++++--- .../next/C API/2020-03-24-09-27-10.bpo-40052.27P2KG.rst | 1 + Objects/call.c | 7 ++++++- 3 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-03-24-09-27-10.bpo-40052.27P2KG.rst --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -82,14 +82,17 @@ _PyVectorcall_Function(PyObject *callabl { PyTypeObject *tp = Py_TYPE(callable); Py_ssize_t offset = tp->tp_vectorcall_offset; - vectorcallfunc *ptr; + union { + char *data; + vectorcallfunc *ptr; + } vc; if (!PyType_HasFeature(tp, _Py_TPFLAGS_HAVE_VECTORCALL)) { return NULL; } assert(PyCallable_Check(callable)); assert(offset > 0); - ptr = (vectorcallfunc*)(((char *)callable) + offset); - return *ptr; + vc.data = (char *)callable + offset; + return *vc.ptr; } /* Call the callable object 'callable' with the "vectorcall" calling --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-03-24-09-27-10.bpo-40052.27P2KG.rst @@ -0,0 +1 @@ +Fix an alignment build warning/error in function ``PyVectorcall_Function()`` publicly exposed by ``abstract.h``. \ No newline at end of file --- a/Objects/call.c +++ b/Objects/call.c @@ -173,6 +173,11 @@ _PyObject_MakeTpCall(PyObject *callable, PyObject * PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) { + union { + char *data; + vectorcallfunc *ptr; + } vc; + /* get vectorcallfunc as in _PyVectorcall_Function, but without * the _Py_TPFLAGS_HAVE_VECTORCALL check */ Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset; @@ -181,7 +186,8 @@ PyVectorcall_Call(PyObject *callable, Py Py_TYPE(callable)->tp_name); return NULL; } - vectorcallfunc func = *(vectorcallfunc *)(((char *)callable) + offset); + vc.data = (char *)callable + offset; + vectorcallfunc func = *vc.ptr; if (func == NULL) { PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall", Py_TYPE(callable)->tp_name);