bpo-40052: Fix alignment issue in PyVectorcall_Function() (GH-23999)

```
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.
```
Co-Authored-By: Andreas Schneider <asn@cryptomilk.org>
Co-Authored-By: Antoine Pitrou <antoine@python.org>
This commit is contained in:
Petr Viktorin 2020-12-30 00:32:07 +01:00 committed by GitHub
parent 2edfc86f69
commit 056c08211b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 7 additions and 4 deletions

View File

@ -63,7 +63,7 @@ PyVectorcall_Function(PyObject *callable)
{ {
PyTypeObject *tp; PyTypeObject *tp;
Py_ssize_t offset; Py_ssize_t offset;
vectorcallfunc *ptr; vectorcallfunc ptr;
assert(callable != NULL); assert(callable != NULL);
tp = Py_TYPE(callable); tp = Py_TYPE(callable);
@ -73,8 +73,8 @@ PyVectorcall_Function(PyObject *callable)
assert(PyCallable_Check(callable)); assert(PyCallable_Check(callable));
offset = tp->tp_vectorcall_offset; offset = tp->tp_vectorcall_offset;
assert(offset > 0); assert(offset > 0);
ptr = (vectorcallfunc *)(((char *)callable) + offset); memcpy(&ptr, (char *) callable + offset, sizeof(ptr));
return *ptr; return ptr;
} }
/* Call the callable object 'callable' with the "vectorcall" calling /* Call the callable object 'callable' with the "vectorcall" calling

View File

@ -0,0 +1,2 @@
Fix an alignment build warning/error in function ``PyVectorcall_Function()``.
Patch by Andreas Schneider, Antoine Pitrou and Petr Viktorin.

View File

@ -205,6 +205,7 @@ PyObject *
PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs)
{ {
PyThreadState *tstate = _PyThreadState_GET(); PyThreadState *tstate = _PyThreadState_GET();
vectorcallfunc func;
/* get vectorcallfunc as in PyVectorcall_Function, but without /* get vectorcallfunc as in PyVectorcall_Function, but without
* the Py_TPFLAGS_HAVE_VECTORCALL check */ * the Py_TPFLAGS_HAVE_VECTORCALL check */
@ -215,7 +216,7 @@ PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs)
Py_TYPE(callable)->tp_name); Py_TYPE(callable)->tp_name);
return NULL; return NULL;
} }
vectorcallfunc func = *(vectorcallfunc *)(((char *)callable) + offset); memcpy(&func, (char *) callable + offset, sizeof(func));
if (func == NULL) { if (func == NULL) {
_PyErr_Format(tstate, PyExc_TypeError, _PyErr_Format(tstate, PyExc_TypeError,
"'%.200s' object does not support vectorcall", "'%.200s' object does not support vectorcall",