[pypy-commit] cffi default: Arithmetic using "void *" should work; at least it does in gcc without
arigo
noreply at buildbot.pypy.org
Sat Nov 9 09:09:58 CET 2013
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r1395:88d2b9436efd
Date: 2013-11-09 09:09 +0100
http://bitbucket.org/cffi/cffi/changeset/88d2b9436efd/
Log: Arithmetic using "void *" should work; at least it does in gcc
without warning.
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -2050,7 +2050,7 @@
static PyObject *
_cdata_add_or_sub(PyObject *v, PyObject *w, int sign)
{
- Py_ssize_t i;
+ Py_ssize_t i, itemsize;
CDataObject *cd;
CTypeDescrObject *ctptr;
@@ -2073,14 +2073,19 @@
cd->c_type->ct_name);
return NULL;
}
- if (ctptr->ct_itemdescr->ct_size < 0) {
- PyErr_Format(PyExc_TypeError,
- "ctype '%s' points to items of unknown size",
- cd->c_type->ct_name);
- return NULL;
- }
- return new_simple_cdata(cd->c_data + i * ctptr->ct_itemdescr->ct_size,
- ctptr);
+ itemsize = ctptr->ct_itemdescr->ct_size;
+ if (itemsize < 0) {
+ if (ctptr->ct_flags & CT_IS_VOID_PTR) {
+ itemsize = 1;
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "ctype '%s' points to items of unknown size",
+ cd->c_type->ct_name);
+ return NULL;
+ }
+ }
+ return new_simple_cdata(cd->c_data + i * itemsize, ctptr);
not_implemented:
Py_INCREF(Py_NotImplemented);
@@ -2101,18 +2106,23 @@
CDataObject *cdw = (CDataObject *)w;
CTypeDescrObject *ct = cdw->c_type;
Py_ssize_t diff;
+ Py_ssize_t itemsize;
if (ct->ct_flags & CT_ARRAY) /* ptr_to_T - array_of_T: ok */
ct = (CTypeDescrObject *)ct->ct_stuff;
+ itemsize = ct->ct_itemdescr->ct_size;
+ if (ct->ct_flags & CT_IS_VOID_PTR)
+ itemsize = 1;
+
if (ct != cdv->c_type || !(ct->ct_flags & CT_POINTER) ||
- (ct->ct_itemdescr->ct_size <= 0)) {
+ (itemsize <= 0)) {
PyErr_Format(PyExc_TypeError,
"cannot subtract cdata '%s' and cdata '%s'",
cdv->c_type->ct_name, ct->ct_name);
return NULL;
}
- diff = (cdv->c_data - cdw->c_data) / ct->ct_itemdescr->ct_size;
+ diff = (cdv->c_data - cdw->c_data) / itemsize;
#if PY_MAJOR_VERSION < 3
return PyInt_FromSsize_t(diff);
#else
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -1642,9 +1642,6 @@
def test_void_errors():
py.test.raises(ValueError, alignof, new_void_type())
py.test.raises(TypeError, newp, new_pointer_type(new_void_type()), None)
- x = cast(new_pointer_type(new_void_type()), 42)
- py.test.raises(TypeError, "x + 1")
- py.test.raises(TypeError, "x - 1")
def test_too_many_items():
BChar = new_primitive_type("char")
@@ -3108,6 +3105,18 @@
py.test.raises(TypeError, "p[1:5] = b'XYZT'")
py.test.raises(TypeError, "p[1:5] = [1, 2, 3, 4]")
+def test_void_p_arithmetic():
+ BVoid = new_void_type()
+ BInt = new_primitive_type("intptr_t")
+ p = cast(new_pointer_type(BVoid), 100000)
+ assert int(cast(BInt, p)) == 100000
+ assert int(cast(BInt, p + 42)) == 100042
+ assert int(cast(BInt, p - (-42))) == 100042
+ assert (p + 42) - p == 42
+ q = cast(new_pointer_type(new_primitive_type("char")), 100000)
+ py.test.raises(TypeError, "p - q")
+ py.test.raises(TypeError, "q - p")
+
def test_version():
# this test is here mostly for PyPy
More information about the pypy-commit
mailing list