Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r97017:69d0c4bbdf2f
Date: 2019-07-23 06:50 +0200
http://bitbucket.org/pypy/pypy/changeset/69d0c4bbdf2f/

Log:    update to cffi/f34ec7d90cd6

diff --git a/extra_tests/cffi_tests/cffi1/test_recompiler.py 
b/extra_tests/cffi_tests/cffi1/test_recompiler.py
--- a/extra_tests/cffi_tests/cffi1/test_recompiler.py
+++ b/extra_tests/cffi_tests/cffi1/test_recompiler.py
@@ -2413,3 +2413,15 @@
     a = ffi.new("struct A *")
     assert ffi.sizeof(a[0]) == ffi.sizeof("unsigned")
     assert ffi.sizeof(b[0]) == ffi.sizeof(a[0])
+
+def test_struct_with_func_with_struct_arg():
+    ffi = FFI()
+    ffi.cdef("""struct BinaryTree {
+            int (* CompareKey)(struct BinaryTree tree);
+        };""")
+    lib = verify(ffi, "test_struct_with_func_with_struct_arg", """
+        struct BinaryTree {
+            int (* CompareKey)(struct BinaryTree tree);
+        };
+    """)
+    py.test.raises(RuntimeError, ffi.new, "struct BinaryTree *")
diff --git a/pypy/module/_cffi_backend/realize_c_type.py 
b/pypy/module/_cffi_backend/realize_c_type.py
--- a/pypy/module/_cffi_backend/realize_c_type.py
+++ b/pypy/module/_cffi_backend/realize_c_type.py
@@ -405,6 +405,20 @@
     if from_ffi and ffi.cached_types[index] is not None:
         return ffi.cached_types[index]
 
+    opcodes[index] = rffi.cast(rffi.VOIDP, 255)
+    try:
+        x = realize_c_type_or_func_now(ffi, op, opcodes, index)
+    finally:
+        if opcodes[index] == rffi.cast(rffi.VOIDP, 255):
+            opcodes[index] = op
+
+    if from_ffi:
+        assert ffi.cached_types[index] is None or ffi.cached_types[index] is x
+        ffi.cached_types[index] = x
+
+    return x
+
+def realize_c_type_or_func_now(ffi, op, opcodes, index):
     case = getop(op)
 
     if case == cffi_opcode.OP_PRIMITIVE:
@@ -446,13 +460,16 @@
                                       'c_type_index')
         x = realize_c_type_or_func(ffi, ffi.ctxobj.ctx.c_types, type_index)
 
+    elif case == 255:
+        raise oefmt(ffi.space.w_RuntimeError,
+            "found a situation in which we try to build a type recursively.  "
+            "This is known to occur e.g. in ``struct s { void(*callable)"
+            "(struct s); }''.  Please report if you get this error and "
+            "really need support for your case.")
+
     else:
         raise oefmt(ffi.space.w_NotImplementedError, "op=%d", case)
 
-    if from_ffi:
-        assert ffi.cached_types[index] is None or ffi.cached_types[index] is x
-        ffi.cached_types[index] = x
-
     return x
 
 
diff --git a/pypy/module/_cffi_backend/test/test_recompiler.py 
b/pypy/module/_cffi_backend/test/test_recompiler.py
--- a/pypy/module/_cffi_backend/test/test_recompiler.py
+++ b/pypy/module/_cffi_backend/test/test_recompiler.py
@@ -2140,3 +2140,19 @@
         assert seen == [2 * 4, p]
         ffi.release(p)    # no effect
         assert seen == [2 * 4, p]
+
+    def test_struct_with_func_with_struct_arg(self):
+        ffi, lib = self.prepare("""struct BinaryTree {
+                int (* CompareKey)(struct BinaryTree tree);
+            };""",
+            "test_struct_with_func_with_struct_arg", """
+            struct BinaryTree {
+                int (* CompareKey)(struct BinaryTree tree);
+            };
+        """)
+        e = raises(RuntimeError, ffi.new, "struct BinaryTree *")
+        assert str(e.value) == (
+            "found a situation in which we try to build a type recursively.  "
+            "This is known to occur e.g. in ``struct s { void(*callable)"
+            "(struct s); }''.  Please report if you get this error and "
+            "really need support for your case.")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to