[pypy-commit] cffi default: Fix C integer division. Add modulo.
arigo
pypy.commits at gmail.com
Fri Apr 26 08:16:05 EDT 2019
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r3273:1fc05b4f57de
Date: 2019-04-26 14:15 +0200
http://bitbucket.org/cffi/cffi/changeset/1fc05b4f57de/
Log: Fix C integer division. Add modulo.
diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -868,8 +868,9 @@
elif exprnode.op == '*':
return left * right
elif exprnode.op == '/':
- # do integer division!
- return left // right
+ return self._c_div(left, right)
+ elif exprnode.op == '%':
+ return left - self._c_div(left, right) * right
elif exprnode.op == '<<':
return left << right
elif exprnode.op == '>>':
@@ -884,6 +885,12 @@
raise FFIError(":%d: unsupported expression: expected a "
"simple numeric constant" % exprnode.coord.line)
+ def _c_div(self, a, b):
+ result = a // b
+ if ((a < 0) ^ (b < 0)) and (a % b) != 0:
+ result += 1
+ return result
+
def _build_enum_type(self, explicit_name, decls):
if decls is not None:
partial = False
diff --git a/testing/cffi0/test_verify.py b/testing/cffi0/test_verify.py
--- a/testing/cffi0/test_verify.py
+++ b/testing/cffi0/test_verify.py
@@ -2534,3 +2534,29 @@
x.p = p
x.cyclic = x
del p, x
+
+def test_arithmetic_in_cdef():
+ for a in [0, 11, 15]:
+ ffi = FFI()
+ ffi.cdef("""
+ enum FOO {
+ DIVNN = ((-?) / (-3)),
+ DIVNP = ((-?) / (+3)),
+ DIVPN = ((+?) / (-3)),
+ MODNN = ((-?) % (-3)),
+ MODNP = ((-?) % (+3)),
+ MODPN = ((+?) % (-3)),
+ };
+ """.replace('?', str(a)))
+ lib = ffi.verify("""
+ enum FOO {
+ DIVNN = ((-?) / (-3)),
+ DIVNP = ((-?) / (+3)),
+ DIVPN = ((+?) / (-3)),
+ MODNN = ((-?) % (-3)),
+ MODNP = ((-?) % (+3)),
+ MODPN = ((+?) % (-3)),
+ };
+ """.replace('?', str(a)))
+ # the verify() crashes if the values in the enum are different from
+ # the values we computed ourselves from the cdef()
More information about the pypy-commit
mailing list