[pypy-commit] pypy cpyext-more-slots: merge default into branch

mattip pypy.commits at gmail.com
Sun May 8 15:32:41 EDT 2016


Author: Matti Picus <matti.picus at gmail.com>
Branch: cpyext-more-slots
Changeset: r84314:eef6d2175abb
Date: 2016-05-08 22:31 +0300
http://bitbucket.org/pypy/pypy/changeset/eef6d2175abb/

Log:	merge default into branch

diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py
--- a/lib_pypy/cffi/api.py
+++ b/lib_pypy/cffi/api.py
@@ -397,20 +397,7 @@
         data.  Later, when this new cdata object is garbage-collected,
         'destructor(old_cdata_object)' will be called.
         """
-        try:
-            gcp = self._backend.gcp
-        except AttributeError:
-            pass
-        else:
-            return gcp(cdata, destructor)
-        #
-        with self._lock:
-            try:
-                gc_weakrefs = self.gc_weakrefs
-            except AttributeError:
-                from .gc_weakref import GcWeakrefs
-                gc_weakrefs = self.gc_weakrefs = GcWeakrefs(self)
-            return gc_weakrefs.build(cdata, destructor)
+        return self._backend.gcp(cdata, destructor)
 
     def _get_cached_btype(self, type):
         assert self._lock.acquire(False) is False
diff --git a/lib_pypy/cffi/backend_ctypes.py b/lib_pypy/cffi/backend_ctypes.py
--- a/lib_pypy/cffi/backend_ctypes.py
+++ b/lib_pypy/cffi/backend_ctypes.py
@@ -460,6 +460,11 @@
                         return x._value
                     raise TypeError("character expected, got %s" %
                                     type(x).__name__)
+                def __nonzero__(self):
+                    return ord(self._value) != 0
+            else:
+                def __nonzero__(self):
+                    return self._value != 0
 
             if kind == 'float':
                 @staticmethod
@@ -993,6 +998,31 @@
         assert onerror is None   # XXX not implemented
         return BType(source, error)
 
+    def gcp(self, cdata, destructor):
+        BType = self.typeof(cdata)
+
+        if destructor is None:
+            if not (hasattr(BType, '_gcp_type') and
+                    BType._gcp_type is BType):
+                raise TypeError("Can remove destructor only on a object "
+                                "previously returned by ffi.gc()")
+            cdata._destructor = None
+            return None
+
+        try:
+            gcp_type = BType._gcp_type
+        except AttributeError:
+            class CTypesDataGcp(BType):
+                __slots__ = ['_orig', '_destructor']
+                def __del__(self):
+                    if self._destructor is not None:
+                        self._destructor(self._orig)
+            gcp_type = BType._gcp_type = CTypesDataGcp
+        new_cdata = self.cast(gcp_type, cdata)
+        new_cdata._orig = cdata
+        new_cdata._destructor = destructor
+        return new_cdata
+
     typeof = type
 
     def getcname(self, BType, replace_with):
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -79,3 +79,6 @@
 It is a more flexible way to make RPython finalizers.
 
 .. branch: unpacking-cpython-shortcut
+
+.. branch: cleanups
+
diff --git a/pypy/module/_multibytecodec/app_multibytecodec.py b/pypy/module/_multibytecodec/app_multibytecodec.py
--- a/pypy/module/_multibytecodec/app_multibytecodec.py
+++ b/pypy/module/_multibytecodec/app_multibytecodec.py
@@ -44,8 +44,10 @@
                 self, data))
 
     def reset(self):
-        self.stream.write(MultibyteIncrementalEncoder.encode(
-                self, '', final=True))
+        data = MultibyteIncrementalEncoder.encode(
+            self, '', final=True)
+        if len(data) > 0:
+            self.stream.write(data)
         MultibyteIncrementalEncoder.reset(self)
 
     def writelines(self, lines):
diff --git a/pypy/module/_multibytecodec/test/test_app_stream.py b/pypy/module/_multibytecodec/test/test_app_stream.py
--- a/pypy/module/_multibytecodec/test/test_app_stream.py
+++ b/pypy/module/_multibytecodec/test/test_app_stream.py
@@ -90,3 +90,15 @@
         w.write(u'\u304b')
         w.write(u'\u309a')
         assert w.stream.output == ['\x83m', '', '\x82\xf5']
+
+    def test_writer_seek_no_empty_write(self):
+        # issue #2293: codecs.py will sometimes issue a reset()
+        # on a StreamWriter attached to a file that is not opened
+        # for writing at all.  We must not emit a "write('')"!
+        class FakeFile:
+            def write(self, data):
+                raise IOError("can't write!")
+        #
+        w = self.ShiftJisx0213StreamWriter(FakeFile())
+        w.reset()
+        # assert did not crash
diff --git a/pypy/module/micronumpy/concrete.py b/pypy/module/micronumpy/concrete.py
--- a/pypy/module/micronumpy/concrete.py
+++ b/pypy/module/micronumpy/concrete.py
@@ -258,7 +258,6 @@
         elif space.is_w(w_idx, space.w_None):
             return [NewAxisChunk(), EllipsisChunk()]
         result = []
-        i = 0
         has_ellipsis = False
         has_filter = False
         for w_item in space.fixedview(w_idx):
@@ -274,7 +273,6 @@
                 result.append(NewAxisChunk())
             elif space.isinstance_w(w_item, space.w_slice):
                 result.append(SliceChunk(w_item))
-                i += 1
             elif isinstance(w_item, W_NDimArray) and w_item.get_dtype().is_bool():
                 if has_filter:
                     # in CNumPy, the support for this is incomplete
@@ -287,7 +285,6 @@
                 result.append(IntegerChunk(w_item.descr_int(space)))
             else:
                 result.append(IntegerChunk(w_item))
-                i += 1
         if not has_ellipsis:
             result.append(EllipsisChunk())
         return result
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -199,7 +199,7 @@
     reds='auto')
 
 def call_many_to_many(space, shape, func, in_dtypes, out_dtypes, in_args, out_args):
-    # out must hav been built. func needs no calc_type, is usually an
+    # out must have been built. func needs no calc_type, is usually an
     # external ufunc
     nin = len(in_args)
     in_iters = [None] * nin
@@ -806,7 +806,6 @@
     indexlen = len(indexes_w)
     dtype = arr.get_dtype()
     iter = PureShapeIter(iter_shape, indexes_w)
-    indexlen = len(indexes_w)
     while not iter.done():
         getitem_int_driver.jit_merge_point(shapelen=shapelen, indexlen=indexlen,
                                            dtype=dtype, prefixlen=prefixlen)
diff --git a/pypy/module/micronumpy/ndarray.py b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -231,11 +231,11 @@
                     dim = i
                     idx = c.w_idx
                     chunks.pop(i)
-                    chunks.insert(0, SliceChunk(space.newslice(space.wrap(0), 
+                    chunks.insert(0, SliceChunk(space.newslice(space.wrap(0),
                                  space.w_None, space.w_None)))
                     break
             if dim > 0:
-                view = self.implementation.swapaxes(space, self, 0, dim) 
+                view = self.implementation.swapaxes(space, self, 0, dim)
             if dim >= 0:
                 view = new_view(space, self, chunks)
                 view.setitem_filter(space, idx, val_arr)
@@ -563,7 +563,7 @@
         l_w = []
         for i in range(self.get_shape()[0]):
             item_w = self.descr_getitem(space, space.wrap(i))
-            if (isinstance(item_w, W_NDimArray) or 
+            if (isinstance(item_w, W_NDimArray) or
                     isinstance(item_w, boxes.W_GenericBox)):
                 l_w.append(space.call_method(item_w, "tolist"))
             else:
@@ -740,7 +740,7 @@
                         space.str_w(self.get_dtype().descr_repr(space)),
                         space.str_w(new_dtype.descr_repr(space)), casting)
         order  = order_converter(space, space.wrap(order), self.get_order())
-        if (not copy and new_dtype == self.get_dtype() 
+        if (not copy and new_dtype == self.get_dtype()
                 and (order in (NPY.KEEPORDER, NPY.ANYORDER) or order == self.get_order())
                 and (subok or type(self) is W_NDimArray)):
             return self
diff --git a/pypy/module/micronumpy/strides.py b/pypy/module/micronumpy/strides.py
--- a/pypy/module/micronumpy/strides.py
+++ b/pypy/module/micronumpy/strides.py
@@ -1,14 +1,13 @@
 from pypy.interpreter.error import oefmt
 from rpython.rlib import jit
-from pypy.module.micronumpy import support, constants as NPY
+from pypy.module.micronumpy import constants as NPY
 from pypy.module.micronumpy.base import W_NDimArray
 
 
 # structures to describe slicing
 
 class BaseChunk(object):
-    _attrs_ = ['step','out_dim']
-    pass
+    _attrs_ = ['step', 'out_dim']
 
 
 class Chunk(BaseChunk):
@@ -36,6 +35,7 @@
 class IntegerChunk(BaseChunk):
     input_dim = 1
     out_dim = 0
+
     def __init__(self, w_idx):
         self.w_idx = w_idx
 
@@ -70,6 +70,7 @@
 class EllipsisChunk(BaseChunk):
     input_dim = 0
     out_dim = 0
+
     def __init__(self):
         pass
 
@@ -80,6 +81,7 @@
 class BooleanChunk(BaseChunk):
     input_dim = 1
     out_dim = 1
+
     def __init__(self, w_idx):
         self.w_idx = w_idx
 
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
@@ -56,7 +56,7 @@
         max = int(max)
         p = ffi.cast(c_decl, min)
         assert p != min       # no __eq__(int)
-        assert bool(p) is True
+        assert bool(p) is bool(min)
         assert int(p) == min
         p = ffi.cast(c_decl, max)
         assert int(p) == max
@@ -285,7 +285,9 @@
         assert ffi.new("char*", b"\xff")[0] == b'\xff'
         assert ffi.new("char*")[0] == b'\x00'
         assert int(ffi.cast("char", 300)) == 300 - 256
-        assert bool(ffi.cast("char", 0))
+        assert not bool(ffi.cast("char", 0))
+        assert bool(ffi.cast("char", 1))
+        assert bool(ffi.cast("char", 255))
         py.test.raises(TypeError, ffi.new, "char*", 32)
         py.test.raises(TypeError, ffi.new, "char*", u+"x")
         py.test.raises(TypeError, ffi.new, "char*", b"foo")
@@ -326,7 +328,11 @@
             py.test.raises(TypeError, ffi.new, "wchar_t*", u+'\U00012345')
         assert ffi.new("wchar_t*")[0] == u+'\x00'
         assert int(ffi.cast("wchar_t", 300)) == 300
-        assert bool(ffi.cast("wchar_t", 0))
+        assert not bool(ffi.cast("wchar_t", 0))
+        assert bool(ffi.cast("wchar_t", 1))
+        assert bool(ffi.cast("wchar_t", 65535))
+        if SIZE_OF_WCHAR > 2:
+            assert bool(ffi.cast("wchar_t", 65536))
         py.test.raises(TypeError, ffi.new, "wchar_t*", 32)
         py.test.raises(TypeError, ffi.new, "wchar_t*", "foo")
         #
@@ -1523,21 +1529,30 @@
         import gc; gc.collect(); gc.collect(); gc.collect()
         assert seen == [3]
 
+    def test_gc_disable(self):
+        ffi = FFI(backend=self.Backend())
+        p = ffi.new("int *", 123)
+        py.test.raises(TypeError, ffi.gc, p, None)
+        seen = []
+        q1 = ffi.gc(p, lambda p: seen.append(1))
+        q2 = ffi.gc(q1, lambda p: seen.append(2))
+        import gc; gc.collect()
+        assert seen == []
+        assert ffi.gc(q1, None) is None
+        del q1, q2
+        import gc; gc.collect(); gc.collect(); gc.collect()
+        assert seen == [2]
+
     def test_gc_finite_list(self):
         ffi = FFI(backend=self.Backend())
-        public = not hasattr(ffi._backend, 'gcp')
         p = ffi.new("int *", 123)
         keepalive = []
         for i in range(10):
             keepalive.append(ffi.gc(p, lambda p: None))
-            if public:
-                assert len(ffi.gc_weakrefs.data) == i + 1
         del keepalive[:]
         import gc; gc.collect(); gc.collect()
         for i in range(10):
             keepalive.append(ffi.gc(p, lambda p: None))
-        if public:
-            assert len(ffi.gc_weakrefs.data) == 10
 
     def test_CData_CType(self):
         ffi = FFI(backend=self.Backend())
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py
@@ -467,12 +467,12 @@
 
     def test_introspect_order(self):
         ffi = FFI()
-        ffi.cdef("union aaa { int a; }; typedef struct ccc { int a; } b;")
-        ffi.cdef("union g   { int a; }; typedef struct cc  { int a; } bbb;")
-        ffi.cdef("union aa  { int a; }; typedef struct a   { int a; } bb;")
-        assert ffi.list_types() == (['b', 'bb', 'bbb'],
-                                    ['a', 'cc', 'ccc'],
-                                    ['aa', 'aaa', 'g'])
+        ffi.cdef("union CFFIaaa { int a; }; typedef struct CFFIccc { int a; } CFFIb;")
+        ffi.cdef("union CFFIg   { int a; }; typedef struct CFFIcc  { int a; } CFFIbbb;")
+        ffi.cdef("union CFFIaa  { int a; }; typedef struct CFFIa   { int a; } CFFIbb;")
+        assert ffi.list_types() == (['CFFIb', 'CFFIbb', 'CFFIbbb'],
+                                    ['CFFIa', 'CFFIcc', 'CFFIccc'],
+                                    ['CFFIaa', 'CFFIaaa', 'CFFIg'])
 
     def test_unpack(self):
         ffi = FFI()
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_new_ffi_1.py
@@ -139,7 +139,7 @@
         max = int(max)
         p = ffi.cast(c_decl, min)
         assert p != min       # no __eq__(int)
-        assert bool(p) is True
+        assert bool(p) is bool(min)
         assert int(p) == min
         p = ffi.cast(c_decl, max)
         assert int(p) == max
@@ -351,7 +351,9 @@
         assert ffi.new("char*", b"\xff")[0] == b'\xff'
         assert ffi.new("char*")[0] == b'\x00'
         assert int(ffi.cast("char", 300)) == 300 - 256
-        assert bool(ffi.cast("char", 0))
+        assert not bool(ffi.cast("char", 0))
+        assert bool(ffi.cast("char", 1))
+        assert bool(ffi.cast("char", 255))
         py.test.raises(TypeError, ffi.new, "char*", 32)
         py.test.raises(TypeError, ffi.new, "char*", u+"x")
         py.test.raises(TypeError, ffi.new, "char*", b"foo")
@@ -391,7 +393,11 @@
             py.test.raises(TypeError, ffi.new, "wchar_t*", u+'\U00012345')
         assert ffi.new("wchar_t*")[0] == u+'\x00'
         assert int(ffi.cast("wchar_t", 300)) == 300
-        assert bool(ffi.cast("wchar_t", 0))
+        assert not bool(ffi.cast("wchar_t", 0))
+        assert bool(ffi.cast("wchar_t", 1))
+        assert bool(ffi.cast("wchar_t", 65535))
+        if SIZE_OF_WCHAR > 2:
+            assert bool(ffi.cast("wchar_t", 65536))
         py.test.raises(TypeError, ffi.new, "wchar_t*", 32)
         py.test.raises(TypeError, ffi.new, "wchar_t*", "foo")
         #
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py
@@ -1898,14 +1898,14 @@
 
 def test_introspect_order():
     ffi = FFI()
-    ffi.cdef("union aaa { int a; }; typedef struct ccc { int a; } b;")
-    ffi.cdef("union g   { int a; }; typedef struct cc  { int a; } bbb;")
-    ffi.cdef("union aa  { int a; }; typedef struct a   { int a; } bb;")
+    ffi.cdef("union CFFIaaa { int a; }; typedef struct CFFIccc { int a; } CFFIb;")
+    ffi.cdef("union CFFIg   { int a; }; typedef struct CFFIcc  { int a; } CFFIbbb;")
+    ffi.cdef("union CFFIaa  { int a; }; typedef struct CFFIa   { int a; } CFFIbb;")
     verify(ffi, "test_introspect_order", """
-        union aaa { int a; }; typedef struct ccc { int a; } b;
-        union g   { int a; }; typedef struct cc  { int a; } bbb;
-        union aa  { int a; }; typedef struct a   { int a; } bb;
+        union CFFIaaa { int a; }; typedef struct CFFIccc { int a; } CFFIb;
+        union CFFIg   { int a; }; typedef struct CFFIcc  { int a; } CFFIbbb;
+        union CFFIaa  { int a; }; typedef struct CFFIa   { int a; } CFFIbb;
     """)
-    assert ffi.list_types() == (['b', 'bb', 'bbb'],
-                                    ['a', 'cc', 'ccc'],
-                                    ['aa', 'aaa', 'g'])
+    assert ffi.list_types() == (['CFFIb', 'CFFIbb', 'CFFIbbb'],
+                                ['CFFIa', 'CFFIcc', 'CFFIccc'],
+                                ['CFFIaa', 'CFFIaaa', 'CFFIg'])
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_zdist.py b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_zdist.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_zdist.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_zdist.py
@@ -280,6 +280,14 @@
             pass
         with open("setup.py", "w") as f:
             f.write("""if 1:
+                # https://bugs.python.org/issue23246
+                import sys
+                if sys.platform == 'win32':
+                    try:
+                        import setuptools
+                    except ImportError:
+                        pass
+
                 import cffi
                 ffi = cffi.FFI()
                 ffi.set_source("pack1.mymod", "/*code would be here*/")
diff --git a/pypy/module/test_lib_pypy/cffi_tests/embedding/test_basic.py b/pypy/module/test_lib_pypy/cffi_tests/embedding/test_basic.py
--- a/pypy/module/test_lib_pypy/cffi_tests/embedding/test_basic.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/embedding/test_basic.py
@@ -80,8 +80,21 @@
             # find a solution to that: we could hack sys.path inside the
             # script run here, but we can't hack it in the same way in
             # execute().
-            output = self._run([sys.executable,
-                                os.path.join(local_dir, filename)])
+            pathname = os.path.join(path, filename)
+            with open(pathname, 'w') as g:
+                g.write('''
+# https://bugs.python.org/issue23246
+import sys
+if sys.platform == 'win32':
+    try:
+        import setuptools
+    except ImportError:
+        pass
+''')
+                with open(os.path.join(local_dir, filename), 'r') as f:
+                    g.write(f.read())
+
+            output = self._run([sys.executable, pathname])
             match = re.compile(r"\bFILENAME: (.+)").search(output)
             assert match
             dynamic_lib_name = match.group(1)
diff --git a/pypy/module/test_lib_pypy/cffi_tests/udir.py b/pypy/module/test_lib_pypy/cffi_tests/udir.py
--- a/pypy/module/test_lib_pypy/cffi_tests/udir.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/udir.py
@@ -1,4 +1,14 @@
 # Generated by pypy/tool/import_cffi.py
 import py
+import sys
 
 udir = py.path.local.make_numbered_dir(prefix = 'ffi-')
+
+
+# Windows-only workaround for some configurations: see
+# https://bugs.python.org/issue23246 (Python 2.7.9)
+if sys.platform == 'win32':
+    try:
+        import setuptools
+    except ImportError:
+        pass
diff --git a/rpython/jit/metainterp/optimizeopt/intutils.py b/rpython/jit/metainterp/optimizeopt/intutils.py
--- a/rpython/jit/metainterp/optimizeopt/intutils.py
+++ b/rpython/jit/metainterp/optimizeopt/intutils.py
@@ -1,5 +1,8 @@
+import sys
 from rpython.rlib.rarithmetic import ovfcheck, LONG_BIT, maxint, is_valid_int
 from rpython.rlib.objectmodel import we_are_translated
+from rpython.rtyper.lltypesystem import lltype
+from rpython.rtyper.lltypesystem.lloperation import llop
 from rpython.jit.metainterp.resoperation import rop, ResOperation
 from rpython.jit.metainterp.optimizeopt.info import AbstractInfo, INFO_NONNULL,\
      INFO_UNKNOWN, INFO_NULL
@@ -174,15 +177,13 @@
     def div_bound(self, other):
         if self.has_upper and self.has_lower and \
            other.has_upper and other.has_lower and \
-           not other.contains(0):
-            try:
-                vals = (ovfcheck(self.upper / other.upper),
-                        ovfcheck(self.upper / other.lower),
-                        ovfcheck(self.lower / other.upper),
-                        ovfcheck(self.lower / other.lower))
-                return IntBound(min4(vals), max4(vals))
-            except OverflowError:
-                return IntUnbounded()
+           not other.contains(0) and self.lower > (-sys.maxint-1):
+            vals = (
+                llop.int_floordiv(lltype.Signed, self.upper, other.upper),
+                llop.int_floordiv(lltype.Signed, self.upper, other.lower),
+                llop.int_floordiv(lltype.Signed, self.lower, other.upper),
+                llop.int_floordiv(lltype.Signed, self.lower, other.lower))
+            return IntBound(min4(vals), max4(vals))
         else:
             return IntUnbounded()
 
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_intbound.py b/rpython/jit/metainterp/optimizeopt/test/test_intbound.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_intbound.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_intbound.py
@@ -240,6 +240,8 @@
 
 
 def test_div_bound():
+    from rpython.rtyper.lltypesystem import lltype
+    from rpython.rtyper.lltypesystem.lloperation import llop
     for _, _, b1 in some_bounds():
         for _, _, b2 in some_bounds():
             b3 = b1.div_bound(b2)
@@ -247,7 +249,8 @@
                 for n2 in nbr:
                     if b1.contains(n1) and b2.contains(n2):
                         if n2 != 0:
-                            assert b3.contains(n1 / n2)
+                            assert b3.contains(
+                                llop.int_floordiv(lltype.Signed, n1, n2))
 
     a=bound(2, 4).div_bound(bound(1, 2))
     assert not a.contains(0)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -5529,6 +5529,27 @@
         """
         self.optimize_loop(ops, expected)
 
+    def test_division_bound_bug(self):
+        ops = """
+        [i4]
+        i1 = int_ge(i4, -50)
+        guard_true(i1) []
+        i2 = int_le(i4, -40)
+        guard_true(i2) []
+        # here, -50 <= i4 <= -40
+
+        i5 = int_floordiv(i4, 30)
+        # here, we know that that i5 == -1  (C-style handling of negatives!)
+        escape_n(i5)
+        jump(i4)
+        """
+        expected = """
+        [i4, i5]
+        escape_n(-1)
+        jump(i4, -1)
+        """
+        self.optimize_loop(ops, expected)
+
     def test_subsub_ovf(self):
         ops = """
         [i0]


More information about the pypy-commit mailing list